调整另一个行的大小时,调整JTextPane的行大小

时间:2012-12-13 15:30:15

标签: java swing resize line jtextpane

我有一个JTextPane(1),另一个是它的旁边(2)。我已同步它们,如果在(2)中输入一行,则在(1)中输入一行,但是当我插入图像(24px)时,(2)自动调整行长度,但(1)不会当然要调整大小。

如何制作“何时(2)调整大小,调整大小(1)”的方法?

我已尝试在(2)中插入图像,在(1)中插入黑色图像(1px,24px),但问题是如果在(2)中插入了许多图像,转到一个新行,其中(1)只是将它们添加到一行上,(1)获得一个水平滚动条。对不起,但我不能缩短它......

public class SSCCE extends JFrame {

    private JPanel contentPane;
    int wrapme=0;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    SSCCE frame = new SSCCE();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public SSCCE() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 338);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JScrollPane scrollName = new JScrollPane();
        scrollName.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
        scrollName.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        scrollName.setBounds(10, 11, 99, 207);
        contentPane.add(scrollName);

        final JTextPane name = new JTextPane();

        name.setEditable(false);
        scrollName.setViewportView(name);

        JScrollPane scrollChat = new JScrollPane();
        scrollChat.setBounds(114, 11, 310, 207);
        contentPane.add(scrollChat);

        final JTextPane chat = new JTextPane();
        chat.setText("Enter something!");
        chat.setEditable(false);
        scrollChat.setViewportView(chat);
        scrollChat.getVerticalScrollBar().setModel(scrollName.getVerticalScrollBar().getModel());

        final JTextArea chatEnter = new JTextArea();
        chatEnter.setBounds(10, 229, 414, 60);
        contentPane.add(chatEnter);

        final StyledDocument nameDoc = name.getStyledDocument();
        final StyledDocument chatDoc = chat.getStyledDocument();
        final SimpleAttributeSet right = new SimpleAttributeSet();
        StyleConstants.setForeground(right, Color.GRAY);
        StyleConstants.setAlignment(right, StyleConstants.ALIGN_RIGHT);
        nameDoc.setParagraphAttributes(0, nameDoc.getLength(), right, false);

        final String TEXT_SUBMIT = "text-submit";
        KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
        InputMap input = chatEnter.getInputMap();
        ActionMap actions = chatEnter.getActionMap();
        input.put(enter, TEXT_SUBMIT);
        actions.put(TEXT_SUBMIT, new AbstractAction() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 try {
                    String s = chatEnter.getText();
                    s=s.replaceAll(":\\)", ":\\) ");
                    s=s.replaceAll("  ", " ");
                    //new line in name
                    String text = chatDoc.getText(0, chatDoc.getLength());
                    int count = 1;
                    int i = text.indexOf("\n");
                    while(i>=0){
                        count++;
                        i=text.indexOf("\n", i + 2);
                    }
                    int totalCharacters = chat.getText().length(); 
                    int lineCount = (totalCharacters == 0) ? 1 : 0;

                    try {
                       int offset = totalCharacters; // arbitrary non-zero number
                       while (offset > 0) {
                        offset = Utilities.getRowStart(chat, offset) - 1;
                        lineCount++;
                       }
                    } catch (BadLocationException ex) {
                        ex.printStackTrace();
                    }
                    lineCount-=wrapme;
                    while(count!=lineCount) {
                        nameDoc.insertString(nameDoc.getLength(), "\n", right);
                        count++;
                        wrapme++;
                    }
                    //new line in name End
                    nameDoc.insertString(nameDoc.getLength(), "Martin\n", right);
                    chatDoc.insertString(chatDoc.getLength(), s + "\n", null);
                    chat.select(chatDoc.getLength(), chatDoc.getLength());
                    name.select(nameDoc.getLength(), nameDoc.getLength());
                } catch (BadLocationException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
             }
        });

        ((AbstractDocument) chat.getDocument()).addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(final DocumentEvent de) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        try {
                            StyledDocument doc = (StyledDocument) de.getDocument();
                            int start = Utilities.getRowStart(chat, Math.max(0, de.getOffset() - 1));
                            int end = Utilities.getWordStart(chat, de.getOffset() + de.getLength());

                            String text = doc.getText(start, (end - start)+1);

                                int i = text.indexOf(":)");
                                while (i >= 0) {
                                    final SimpleAttributeSet attrs = new SimpleAttributeSet(doc.getCharacterElement(start + i).getAttributes());
                                    if (StyleConstants.getIcon(attrs) == null) {
                                                StyleConstants.setIcon(attrs, new new ImageIcon(ChatFrame.class.getResource("/smile.png")));

                                        doc.remove(start + i, 2);
                                        doc.insertString(start + i, ":)", attrs);

                                        StyleConstants.setIcon(attrs, new ImageIcon(ChatFrame.class.getResource("/spacer.png")));
                                        nameDoc.insertString(nameDoc.getLength()-6," ", attrs); //6 is "Martin" length

                                    }
                                    i = text.indexOf(":)", i + 2);
                                }
                        } catch (BadLocationException ex) {
                            ex.printStackTrace();
                        }
                    }
                    });
                }
            @Override
            public void removeUpdate(DocumentEvent e) {
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
            }
        });
    }
}

smile.png http://postimage.org/image/vm7e4gvp1/ spacer.png http://postimage.org/image/k0q09iq6l/

1 个答案:

答案 0 :(得分:1)

对于发送的每封邮件,可能最好使用一个主JTextPane(聊天)和多个单独的JTextPanes(或甚至标签)。然后,您可以控制设置所需高度的单个消息标签(或文本窗格)。

可以计算高度,将消息开始和结束偏移传递给modelToView()方法并计算差异。