JTextPane和JTextField之间的文本选择冲突 [英] text selection conflict between JTextPane and JTextField
问题描述
如果存在JTextField,为什么无法以编程方式选择JTextPane中的文本?我认为与焦点有关。 Thx。
Why the text in JTextPane cannot be selected programmatically if there is a JTextField present? Has something to do with focus i think. Thx.
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
public class align extends JFrame {
private align() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addPane(this, "one");
pack();
setVisible(true);
}
public static void main(String[] args) {
align t = new align();
}
private void addPane(JFrame frame, String name) {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
// if the next line is disabled, then the text is JTextPane is correctly highlighted.,,
panel.add(makeField("line1"));
JTextPane p = new JTextPane();
p.setText("abcdef");
p.setSelectionStart(2);
p.setSelectionEnd(4);
p.setFocusable(true);
p.requestFocus();
p.requestDefaultFocus();
panel.add(p);
frame.getContentPane().add(panel);
}
private JComponent makeField(String name) {
JTextField textArea = new JTextField();
textArea.setText(name);
textArea.setEditable(false);
return textArea;
}
}
编辑:
通过在构建框架后触发按键事件来显示所选文本。更好(更长)的解决方案是使用自定义Highlighter和DocumentListener的只读TextPane,使剪贴板在Ctrl-C上保持更新。
Got it to display the selected text by firing the key event after the frame has been built. A better (longer) solution would be to have a read-only TextPane with custom Highlighter and DocumentListener that keeps the clipboard updated on Ctrl-C.
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
new KeyEvent(textPane, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB));
推荐答案
只是为了好玩(毕竟,它是星期五: - 我跟踪了Stanislav的评论,扩展了DefaultCaret以保持选择对于未聚焦的textComponents可见。
Just for fun (after all, it's Friday :-) I followed up Stanislav's comment, extending DefaultCaret to keep the selection visible for unfocused textComponents.
基本想法
- 支持两种选择装饰:专注选择,不专心-selection
- 保持选择亮点的外观尽可能接近LAF默认值,归结为重新使用selectionPainter(只能通过......咳嗽,咳嗽......反射) )
-
傻瓜相信选择始终可见
- support two selection decorations: focused-selection, unfocused-selection
- keep the appearance of the selection highlights as near to LAF default as possible, which boils down to re-using the selectionPainter (accessible only by ... cough, cough .. reflection)
fool super into believing that the selection is always visible
public static class WrappingCaret extends DefaultCaret {
private DefaultCaret delegate;
private HighlightPainter focusedSelectionPainter;
private HighlightPainter unfocusedSelectionPainter;
private boolean focusedSelectionVisible;
public WrappingCaret(JTextComponent target) {
installDelegate((DefaultCaret) target.getCaret());
target.setCaret(this);
}
private void installDelegate(DefaultCaret delegate) {
this.delegate = delegate;
setBlinkRate(delegate.getBlinkRate());
}
private void installSelectionPainters() {
if (delegate instanceof BasicCaret) {
installDefaultPainters();
} else {
try {
Method method = delegate.getClass().getDeclaredMethod(
"getSelectionPainter");
method.setAccessible(true);
focusedSelectionPainter = (HighlightPainter) method
.invoke(delegate);
Constructor<?>[] constructors = focusedSelectionPainter
.getClass().getDeclaredConstructors();
constructors[0].setAccessible(true);
unfocusedSelectionPainter = (HighlightPainter) constructors[0]
.newInstance(getUnfocusedSelectionColor());
} catch (Exception e) {
installDefaultPainters();
}
}
}
private Color getUnfocusedSelectionColor() {
Color first = getComponent().getSelectionColor();
// create a reasonable unfocusedSelectionColor
return PaintUtils.setAlpha(first, 125);
}
private void installDefaultPainters() {
focusedSelectionPainter = super.getSelectionPainter();
unfocusedSelectionPainter = new DefaultHighlightPainter(
getUnfocusedSelectionColor());
}
/**
* @inherited <p>
*/
@Override
public void install(JTextComponent c) {
super.install(c);
installSelectionPainters();
setSelectionVisible(isSelectionVisible());
}
/**
* @inherited <p>
*/
@Override
public void setSelectionVisible(boolean vis) {
focusedSelectionVisible = vis;
super.setSelectionVisible(!isSelectionVisible());
super.setSelectionVisible(true);
}
/**
* @inherited <p>
*/
@Override
protected HighlightPainter getSelectionPainter() {
return focusedSelectionVisible ? focusedSelectionPainter
: unfocusedSelectionPainter;
}
}
享受!
这篇关于JTextPane和JTextField之间的文本选择冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!