同时在2 JTextarea中选择文本

时间:2014-03-27 00:37:44

标签: java swing events jtextarea

我正在尝试一个小应用程序来比较2 JTextarea中包含的两个相似文本。我想知道是否可以从第一个JTextarea中选择文字并自动选择第二个JTeaxtarea上的文字(让我们考虑保证2 JTextarea将具有相同的文字现在)? 我应该分享活动或听众吗? 谢谢

1 个答案:

答案 0 :(得分:2)

如果JTextComponent支持选择模型,那会更容易......

基本上,您可以做的是将ChangeListener附加到JTextArea Caret并监控Caret的更改,更改选择另一个JTextArea作为回应......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;

public class MirrorTextSelection {

    public static void main(String[] args) {
        new MirrorTextSelection();
    }

    public MirrorTextSelection() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JTextArea left;
        private JTextArea right;

        private DefaultHighlighter.DefaultHighlightPainter highlightPainter;

        public TestPane() {

            highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));

            left = new JTextArea(20, 20);
            left.setWrapStyleWord(true);
            left.setLineWrap(true);
            right = new JTextArea(20, 20);
            right.setWrapStyleWord(true);
            right.setLineWrap(true);

            left.setText("I am trying to do a small app that compares two similar texts contained in 2 JTextarea. I am wondering if it's possible to select text from the first JTextarea and automatically select the text on the second JTeaxtarea (lets consider that it's guarantee that the 2 JTextarea will have the same text for now) ? Should I share events or listeners ? Thank you");
            right.setText("I am trying to do a small app that compares two similar texts contained in 2 JTextarea. I am wondering if it's possible to select text from the first JTextarea and automatically select the text on the second JTeaxtarea (lets consider that it's guarantee that the 2 JTextarea will have the same text for now) ? Should I share events or listeners ? Thank you");

            setLayout(new GridLayout(0, 2));

            add(new JScrollPane(left));
            add(new JScrollPane(right));

            left.getCaret().addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    int dot = left.getCaret().getDot();
                    int mark = left.getCaret().getMark();

                    right.setCaretPosition(mark);
                    right.moveCaretPosition(dot);
                }
            });
        }
    }
}

现在,当你运行它时,你会发现右侧似乎没有突出显示......什么?!

选择正在改变,因为组件没有焦点而没有渲染...

相反,您可以使用Highlighter突出显示文字......

private DefaultHighlighter.DefaultHighlightPainter highlightPainter;
//...
highlightPainter = new DefaultHighlighter.DefaultHighlightPainter(UIManager.getColor("TextArea.selectionBackground"));

left.getCaret().addChangeListener(new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent e) {
        int dot = left.getCaret().getDot();
        int mark = left.getCaret().getMark();

        right.getHighlighter().removeAllHighlights();
        try {
            int start = Math.min(dot, mark);
            int end = Math.max(dot, mark);
            right.getHighlighter().addHighlight(start, end, highlightPainter);
        } catch (BadLocationException ex) {
            ex.printStackTrace();
        }
    }
});

好的,现在正在使用,您可以控制高亮显示的背景颜色......

还有另一种选择......我们可以将Caret right的{​​{1}}替换为在焦点丢失时无法隐藏选择的JTextArea ... < / p>

public class HighlightCaret extends DefaultCaret {

    @Override
    public void install(JTextComponent c) {
        super.install(c);
        setSelectionVisible(true);
    }

    @Override
    public void focusGained(FocusEvent e) {
        JTextComponent component = getComponent();
        if (component.isEnabled()) {
            if (component.isEditable()) {
                setVisible(true);
            }
            setSelectionVisible(true);
        }
    }

    @Override
    public void focusLost(FocusEvent e) {
        setVisible(false);
    }
}

然后我们将Caret设置为right ...

right.setCaret(nwe HighlightCaret());

这意味着我们不需要Highlighter代码,我们可以坚持使用原始代码,我们不仅可以控制背景选择颜色,还可以控制前景选择颜色......