2011-05-05 51 views
1

如果存在JTextField,为什么JTextPane中的文本无法以编程方式选择?与我关注的焦点有关。谢谢。JTextPane和JTextField之间的文本选择冲突

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

编辑:

得到它由烧制的关键事件框架已建成后显示选定的文本。一个更好的(更长的)解决方案是使用自定义的高亮器和DocumentListener的只读TextPane,使Ctrl-C上的剪贴板更新。

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

请勿使用不推荐的方法,如'JComponent.requestDefaultFocus()'。 – 2011-05-05 18:14:45

+0

请学习并使用java命名约定 – kleopatra 2011-05-06 07:46:40

回答

3

JTextPane文本是选择。麻烦的是,除非组件专注,否则它不会给出任何视觉指示。一旦显示GUI,就尝试对组件进行制表。


所以,我应该释放注意到这?

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

鉴于JTextPane是支持格式的成分,可能使文本大胆斜体例如。

+0

那么,我应该发布注释这个? “亲爱的用户,按Tab键看到选择???”大声笑 – Saideira 2011-05-05 18:16:58

3

也许是这样显示的高亮,你应该使用荧光笔中的所有文本组件:

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

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

聪明的做法。讨厌这种颜色。 ;) – 2011-05-05 18:36:25

+0

是的,如果我需要为美容目的突出显示将工作。我需要真正的剪贴板功能选择。 – Saideira 2011-05-05 19:59:35

+1

@Saideira,那么你只需要一次显示一个选择,因为剪贴板的复制功能只适用于具有焦点的组件。所以这不是问题。 – camickr 2011-05-05 21:15:30

3
p.getCaret().setSelectionVisible(true); 
+0

cool - 我当天学习的东西(到目前为止:-) – kleopatra 2011-05-06 07:53:58

+0

只,如何保持它的方式?一旦窗格经过focusGained/-Lost,选择可见性再次消失。嗯... – kleopatra 2011-05-06 07:57:42

+0

没错。当焦点丢失时,该选择被设置为假,但可以使用自己的脱字符,例如,扩展DefaultCaret并覆盖逻辑。 – StanislavL 2011-05-06 08:13:04

3

只是为了好玩(毕竟,这是星期五:-)我跟进斯坦尼斯的评论,延长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; 
        } 
    
    } 
    

享受!