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

问题描述 投票:2回答:4

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

问候

到目前为止我尝试过:

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

编辑:

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

java swing select
4个回答
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中提供的代码。


2
投票

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

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

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

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

我这样做的事情我会解决问题。

希望能帮助到你!!

问候!。


1
投票

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

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

希望它有所帮助!


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();
            }
        });
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.