JTextPane和JTextField之间的文本选择冲突

时间:2011-05-05 17:31:07

标签: java swing

如果存在JTextField,为什么无法以编程方式选择JTextPane中的文本?我认为与焦点有关。 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上更新剪贴板。

    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
            new KeyEvent(textPane, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB));

4 个答案:

答案 0 :(得分:3)

选择了JTextPane 中的文字。麻烦的是除非组件被聚焦,否则它不会给出任何视觉指示。显示GUI后,尝试使用Tab键选择组件。


  

所以,我应该发布这个吗?

不,您应该重新设计破碎的GUI,使用文本选择来识别感兴趣的文本。文本选择更适合最终用户,而不是应用程序。

鉴于JTextPane是支持格式化的组件,可能会将文字设置为粗体斜体

答案 1 :(得分:3)

也许您应该使用荧光笔,以便突出显示在所有文本组件中:

Highlighter.HighlightPainter yellow = 
    new DefaultHighlighter.DefaultHighlightPainter( Color.YELLOW );

try
{
    textPane.getHighlighter().addHighlight(2, 4, yellow);
}
catch(BadLocationException ble) { System.out.println(ble); }

答案 2 :(得分:3)

p.getCaret().setSelectionVisible(true);

答案 3 :(得分:3)

只是为了好玩(毕竟,这是星期五:-)我跟进了Stanislav的评论,扩展了DefaultCaret以保持选择对于未聚焦的textComponents可见。

基本想法

  • 支持两种选择装饰:聚焦选择,未聚焦选择
  • 保持选择亮点的外观尽可能接近LAF默认值,归结为重新使用selectionPainter(只能通过......咳嗽,咳嗽......反射)
  • 愚弄超级相信选择总是可见的

    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;
        }
    
    }
    

享受!