Java JTextField中的示例文本

Java JTextField中的示例文本,java,swing,jtextfield,Java,Swing,Jtextfield,我正在寻找一种将示例文本放入swing JTextField并使其变灰的方法。然后,在文本字段中输入任何内容后,示例文本应立即消失。有些类似于stackoverflow在用户发布带有标题字段的问题时所做的操作 我希望它已经是JTextField的扩展实现,这样我就可以把它作为一个简单的替代品放进去。任何来自swingx的东西都可以。我想如果没有一种简单的方法可以做到这一点,我的选择可能是覆盖JTextField的paint方法,或许可以这样做 谢谢而不是重写,在字段中输入一个值,然后添加一个Ke

我正在寻找一种将示例文本放入swing JTextField并使其变灰的方法。然后,在文本字段中输入任何内容后,示例文本应立即消失。有些类似于stackoverflow在用户发布带有标题字段的问题时所做的操作

我希望它已经是JTextField的扩展实现,这样我就可以把它作为一个简单的替代品放进去。任何来自swingx的东西都可以。我想如果没有一种简单的方法可以做到这一点,我的选择可能是覆盖JTextField的paint方法,或许可以这样做


谢谢

而不是重写,在字段中输入一个值,然后添加一个
KeyListener
,它将在注册按键笔划时删除该值。也许还可以让它改变前景


您可以将其封装到自己的自定义
JTextField
类中,该类将获取构造函数中的默认文本。

纯文本字段无法实现这一点,但您可以将禁用的
JLabel
放在
JTextField
顶部,并在文本字段获得焦点时将其隐藏。

如果您可以使用外部库,来自的Swing组件具有您所需的功能;它被称为LabeledTextField(),是JIDE公共层(开源项目)的一部分,是免费的。它正在执行mklhmnn建议的操作。

如何使用默认文本初始化文本字段,并为其提供一个焦点侦听器,以便在获得焦点时,如果text.等于默认文本,则调用JTextField上的selectAll()。

按如下方式执行:

  • 使用您喜欢的初始文本定义字符串并设置文本字段:

    String initialText = "Enter your initial text here";
    jTextField1.setText(initialText);
    
  • 将焦点侦听器添加到TextField,如果TextField仍然具有初始值,则会选择TextField的全部内容。您可以键入的任何内容都将替换整个内容,因为它已被选中

    jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
        public void focusGained(java.awt.event.FocusEvent evt) {
           if (jTextField1.getText().equals(initialText)) {
              jTextField1.selectAll();
           }
        }
    });
    
  • 该类提供了所需的功能,而不使用自定义JTextField

    它允许您指定文本字段为空时显示的提示。键入文本后,提示即被删除

    提示实际上是一个
    JLabel
    ,因此您可以自定义字体、前景等:

    JTextField tf7 = new JTextField(10);
    TextPrompt tp7 = new TextPrompt("First Name", tf7);
    tp7.setForeground( Color.RED );
    

    您不能使用键侦听器,因为数据可以通过复制和粘贴等其他方法输入。我不会将此示例文本添加到值字段中,因为使用getText()检索该示例存在风险text@Hover,我首先想到了一个焦点听众,但在OP提到的所谓的标题示例中,文本不会在焦点上消失,而是在开始键入时消失。如果您确实允许粘贴添加DocumentListener可能是一个更好的解决方案。@DavidM,可以重写getText()方法,以防止未键入的示例文本返回。这正是Hovercraft建议的。我正忙着粘贴,没有读他的答案。不,永远,永远,不要在paintComponent内部创建任何东西,而不是JComponents,所有对象都必须准备好,只是为了调用Graphics/2D方法,而不是永远更改其属性too@mKorbel:为什么?你能详细说明或提供参考吗?因为油漆组件被称为1。当重新绘制()需要JComponent时,2。调用repaint()后,3。从每个鼠标和键盘事件,4。当层次结构或容器(添加JComponents、调整大小e.i.)以编程方式更改或触发事件时,5。在本机操作系统中应达到延迟(将此刷新率重载为冻结绘制),6每个事件或此事件要创建一个新的JLabel,也必须使用OutOfMemoryExceptions进行计算,7,相同的问题不要从该块加载映像,将其准备为局部变量,并且仅从数组或按变量拾取name@mKorbel:将JLabel移到外部,感谢您指出这一点。@mKorbel:调试表明,当前的paintComponent()开销在大多数调用中是微不足道的。现在,我只在setBounds()发生更改时调用它们(因此EDT被冻结的时间与setBounds()在外部完成的时间相同)。
    private JLabel l;
    
    JPromptTextField(String prompt) {
        l = new JLabel(prompt, SwingConstants.CENTER);
        l.setForeground(Color.GRAY);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
    
        if (this.getText().length() == 0) {
            // Reshape the label if needed, then paint
    
            final Rectangle mine = this.getBounds();
            final Rectangle its = l.getBounds(); 
            boolean resized = (mine.width != its.width) || (mine.height != its.height);
            boolean moved = (mine.x != its.x) || (mine.y != its.y);
            if (resized || moved)
                l.setBounds(mine);
    
            l.paint(g);
        }
    }