假设我们在JPanel中有两个JTextArea,我希望用户能够在一个选择中使用鼠标选择跨越这两个JTextArea的文本,是否可以在Swing中使用?
此致
到目前为止,我已尝试过:
我尝试将mouselistener添加到这些JTextArea,当mouseEnter时,我在TextArea中选择文本,并以实用方式突出显示文本。这既困难又容易出错,我想也许有更好的方法
修改
感谢您的所有答案和建议。根据答案,我实施了一个基本的解决方案,并将其作为其他人参考的答案。 :)
答案 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();
}
});
}
}