【问题标题】:Select text in 2 JTextarea at the same time同时选择2个JTextarea中的文本
【发布时间】:2014-03-27 09:27:09
【问题描述】:

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

【问题讨论】:

  • similar texts contained in 2 JTextarea & 2 JTextarea will have the same text 文字怎么可能同时“相似”和“相同”?
  • (让我们认为它保证 2 JTextarea 现在将具有相同的文本)

标签: java swing events jtextarea


【解决方案1】:

如果JTextComponent 支持选择模型,这会容易得多...

基本上,您可以做的是将ChangeListener 附加到JTextAreaCaret 并监视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();
        }
    }
});

好的,现在可以了,你可以控制高亮的背景颜色...

还有另一种选择...我们可以将right JTextAreaCaret 替换为在焦点丢失时不隐藏选择的...

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 代码,我们可以坚持使用原始代码,我们不仅可以控制背景选择颜色,还可以控制前景选择颜色...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 2012-08-28
    • 2013-06-26
    • 1970-01-01
    相关资源
    最近更新 更多