Java Swing:选择跨多个textareas的文本

时间:2014-03-05 14:53:49

标签: java swing select

假设我们在JPanel中有两个JTextArea,我希望用户能够在一个选择中使用鼠标选择跨越这两个JTextArea的文本,是否可以在Swing中使用?

此致

到目前为止,我已尝试过:

我尝试将mouselistener添加到这些JTextArea,当mouseEnter时,我在TextArea中选择文本,并以实用方式突出显示文本。这既困难又容易出错,我想也许有更好的方法

修改

感谢您的所有答案和建议。根据答案,我实施了一个基本的解决方案,并将其作为其他人参考的答案。 :)

4 个答案:

答案 0 :(得分:5)

  

当用户在第二个文本中选择文本时,第一个文本区域中的文本保持被选中(文本在高光中)

我认为您的意思是用户在两个不同的文本区域中选择不同的文本。

默认情况下,文本组件仅在文本组件具有焦点时显示所选文本。

简单的答案是创建自定义Caret并覆盖focusLost(...)方法并在方法结束时调用setSelectionVisible(true),以确保即使文本组件没有绘制选择对焦。

以下是该方法的更高版本,允许您为没有焦点的文本组件指定不同的选择背景颜色(如果您愿意):

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class SelectionCaret extends DefaultCaret
{
    private static final Color SELECTION_COLOR = UIManager.getColor("TextField.selectionBackground");

    private Highlighter.HighlightPainter focusedPainter;
    private Highlighter.HighlightPainter unfocusedPainter;

    public SelectionCaret()
    {
        this(SELECTION_COLOR);
    }

    public SelectionCaret(Color unfocusedColor)
    {
        focusedPainter = new DefaultHighlighter.DefaultHighlightPainter(SELECTION_COLOR);
        unfocusedPainter = new DefaultHighlighter.DefaultHighlightPainter(unfocusedColor);

        setBlinkRate( UIManager.getInt("TextField.caretBlinkRate") );
    }

    @Override
    protected Highlighter.HighlightPainter getSelectionPainter()
    {
        return getComponent().hasFocus() ? focusedPainter : unfocusedPainter;
    }

    @Override
    public void focusGained(FocusEvent e)
    {
        setSelectionVisible(false);
        super.focusGained(e);
    }

    @Override
    public void focusLost(FocusEvent e)
    {
        super.focusLost(e);
        setSelectionVisible(true);
    }

    private static void createAndShowUI()
    {
        JTextField textField1 = new JTextField("Text Field1   ");
        JTextField textField2 = new JTextField("Text Field2   ");
        JTextField textField3 = new JTextField("Non Editable   ");
        textField3.setEditable(false);

        textField1.setCaret(new SelectionCaret());
        textField2.setCaret(new SelectionCaret());
        textField3.setCaret(new SelectionCaret());

        textField1.select(5, 11);
        textField2.select(5, 11);
        textField3.select(5, 11);
        ((DefaultCaret)textField1.getCaret()).setSelectionVisible(true);
        ((DefaultCaret)textField2.getCaret()).setSelectionVisible(true);
        ((DefaultCaret)textField3.getCaret()).setSelectionVisible(true);

        JPanel north = new JPanel();
        north.add( new JTextField("Text Field0   ") );
        north.add(textField1);
        north.add(textField2);
        north.add(textField3);

        JFrame frame = new JFrame("Selection Caret");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( north );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

上面的代码基于mKorbel在此posting中提供的代码。

答案 1 :(得分:2)

可能你必须在一个JTextArea中注册事件处理程序,可能有一个特定于属于文本选择的事件类型,然后以编程方式在另一个JTextArea上传播相同的效果。但除此之外没有其他魔力了。

对于您正在查找的事件类型,请关注以下关键字: Swing JTextArea事件侦听器以进行文本选择

如果我的记忆没有失败,那么JTextField会提供一种选择范围内文本的方法。

对于此类问题,请查找:在jTextField中选择文本

我认为这个的方式我会解决问题。

希望它有所帮助!!

问候!

答案 2 :(得分:1)

Usong Swing通常,你不能。它的设计不允许在两个不同的可聚焦对象中进行选择。 但是,您可以使用MouseListeners和JTextComponent中的select(int,int)方法来弯曲它。但要注意,这可能很棘手。

另一个解决方案是只使用一个真正的JTextComponent,并通过在其上绘制一个分隔条或任何你认为合适的图形来划分它。

希望有所帮助!

答案 3 :(得分:0)

基于@ camickr的答案和代码,我实现了一个基本的解决方案(这实现了我的目标,虽然远非优化,你必须在使用它时重构代码):

public class SelectionCaret extends DefaultCaret
{

    private static boolean isselecting = false;

    private static final Color SELECTION_COLOR = UIManager.getColor("TextField.selectionBackground");

    private Highlighter.HighlightPainter focusedPainter;
    private Highlighter.HighlightPainter unfocusedPainter;

    public SelectionCaret()
    {
        this(SELECTION_COLOR);
    }

    public SelectionCaret(Color unfocusedColor)
    {
        focusedPainter = new DefaultHighlighter.DefaultHighlightPainter(SELECTION_COLOR);
        unfocusedPainter = new DefaultHighlighter.DefaultHighlightPainter(unfocusedColor);

        setBlinkRate( UIManager.getInt("TextField.caretBlinkRate") );
    }

    @Override
    protected Highlighter.HighlightPainter getSelectionPainter()
    {
        return getComponent().hasFocus() ? focusedPainter : unfocusedPainter;
    }

    @Override
    public void focusGained(FocusEvent e)
    {
        setSelectionVisible(false);
        super.focusGained(e);
    }

    @Override
    public void focusLost(FocusEvent e)
    {
        super.focusLost(e);
        setSelectionVisible(true);
    }

    private static void createAndShowUI()
    {
        JTextField textField1 = new JTextField("Text Field1   ");
        JTextField textField2 = new JTextField("Text Field2   ");

        textField1.setCaret(new SelectionCaret());
        textField2.setCaret(new SelectionCaret());

        ((DefaultCaret)textField1.getCaret()).setSelectionVisible(true);
        ((DefaultCaret)textField2.getCaret()).setSelectionVisible(true);

        JPanel north = new JPanel();
        north.add(textField1);
        north.add(textField2);

        JFrame frame = new JFrame("Selection Caret");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( north );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );

        north.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {

            }

            @Override
            public void mousePressed(MouseEvent e) {
                SelectionCaret.isselecting = true;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                SelectionCaret.isselecting = false;
            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });

        textField1.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                SelectionCaret.isselecting = true;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                SelectionCaret.isselecting = false;
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                if(SelectionCaret.isselecting) {
                    Robot robot = null;
                    try {
                        robot = new Robot();
                        robot.mousePress(InputEvent.BUTTON1_MASK);
                    } catch (AWTException e1) {
                        e1.printStackTrace();
                    }
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });

        textField2.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {

            }

            @Override
            public void mousePressed(MouseEvent e) {
                SelectionCaret.isselecting = true;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                SelectionCaret.isselecting = false;
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                if(SelectionCaret.isselecting) {
                    Robot robot = null;
                    try {
                        robot = new Robot();
                        robot.mousePress(InputEvent.BUTTON1_MASK);
                    } catch (AWTException e1) {
                        e1.printStackTrace();
                    }
                }

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        });
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}