【问题标题】:Making a JTextField with Vanishing Text使用消失的文本制作 JTextField
【发布时间】:2015-03-06 19:33:24
【问题描述】:

我知道您可以预先将文本输入到 JTextField 中。此文本将显示在 JTextField 中,并且在必须将您自己的文本输入 JTextField 时必须手动删除。例如,考虑这个 JTextField:

cruiseSel = new JTextField ("Selected Cruise:");
cruiseSel.setEditable(false);  
centerP12.add(cruiseSel);
contentPane12.add(centerP12, BorderLayout.CENTER);
Frame12.setVisible(true);

运行上述程序后,将出现一个 JTextField,其中写有“Selected Cruise:”。然后必须手动删除此文本以清除文本字段。

有没有办法在jtextfield中输入文本,因此在GUI打开后,将显示文本,但当jtextfield被选中输入手动文本时,文本会消失?

【问题讨论】:

标签: java swing jtextfield


【解决方案1】:

您可以使用FocusListener,当 JTextField 获得焦点时,清空文本。

当然,您需要一个状态标记来指示它具有默认文本,并且一旦用户输入了文本就不要这样做。在第一次点击 FocusListener 之后或之后,将其移除。

textField.addFocusListener(new FocusAdapter() {
    public void focusGained(FocusEvent e) {
        JTextField source = (JTextField)e.getComponent();
        source.setText("");
        source.removeFocusListener(this);
    }
});

【讨论】:

    【解决方案2】:

    您可以使用SwingX 阅读此How to set Text like Placeholder in JTextfield in swing 我在这里包含示例代码供您使用

    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import org.jdesktop.swingx.prompt.PromptSupport;
    
    public class PromptExample {
    
        public static void main(String[] args) {
            new PromptExample();
        }
    
        public PromptExample() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JTextField bunnies = new JTextField(10);
                    JTextField ponnies = new JTextField(10);
                    JTextField unicorns = new JTextField(10);
                    JTextField fairies = new JTextField(10);
    
                    PromptSupport.setPrompt("Bunnies", bunnies);
                    PromptSupport.setPrompt("Ponnies", ponnies);
                    PromptSupport.setPrompt("Unicorns", unicorns);
                    PromptSupport.setPrompt("Fairies", fairies);
    
                    PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIDE_PROMPT, bunnies);
                    PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.HIGHLIGHT_PROMPT, ponnies);
                    PromptSupport.setFocusBehavior(PromptSupport.FocusBehavior.SHOW_PROMPT, unicorns);
    
                    PromptSupport.setFontStyle(Font.BOLD, bunnies);
                    PromptSupport.setFontStyle(Font.ITALIC, ponnies);
                    PromptSupport.setFontStyle(Font.ITALIC | Font.BOLD, unicorns);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    frame.add(bunnies, gbc);
                    frame.add(ponnies, gbc);
                    frame.add(unicorns, gbc);
                    frame.add(fairies, gbc);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      查看Text Prompt

      它支持此功能以及一些自定义提示行为的特性。

      【讨论】:

        【解决方案4】:

        您要查找的内容称为占位符。我前段时间写过这门课:

        import java.awt.Color;
        import java.awt.FlowLayout;
        import java.awt.Graphics;
        import java.awt.Graphics2D;
        import java.awt.Insets;
        import java.awt.Rectangle;
        import java.awt.RenderingHints;
        import java.awt.event.FocusEvent;
        import java.awt.event.FocusListener;
        
        import javax.swing.JButton;
        import javax.swing.JFrame;
        import javax.swing.JTextField;
        import javax.swing.SwingUtilities;
        import javax.swing.text.BadLocationException;
        import javax.swing.text.Document;
        
        /**
         * @author xehpuk
         */
        public class PlaceholderTextField extends JTextField {
            private static final long serialVersionUID = -5529071085971698388L;
        
            /**
             * The placeholder to be displayed if the text field is empty.
             */
            private String placeholder;
            /**
             * Determines whether the placeholder should be displayed even on focus.
             */
            private boolean paintingOnFocus;
            /**
             * The color the placeholder should be displayed in.
             */
            private Color placeholderColor;
        
            public String getPlaceholder() {
                return placeholder;
            }
        
            public void setPlaceholder(final String placeholder) {
                this.placeholder = placeholder;
                repaint();
            }
        
            public boolean isPaintingOnFocus() {
                return paintingOnFocus;
            }
        
            public void setPaintingOnFocus(final boolean paintingOnFocus) {
                this.paintingOnFocus = paintingOnFocus;
                repaint();
            }
        
            public Color getPlaceholderColor() {
                return placeholderColor;
            }
        
            public void setPlaceholderColor(final Color placeholderColor) {
                this.placeholderColor = placeholderColor;
                repaint();
            }
        
            public PlaceholderTextField() {
                super();
            }
        
            public PlaceholderTextField(final Document doc, final String text, final int columns) {
                super(doc, text, columns);
            }
        
            public PlaceholderTextField(final int columns) {
                super(columns);
            }
        
            public PlaceholderTextField(final String text, final int columns) {
                super(text, columns);
            }
        
            public PlaceholderTextField(final String text) {
                super(text);
            }
        
            {
                addFocusListener(new RepaintFocusListener());
            }
        
            @Override
            protected void paintComponent(final Graphics g) {
                super.paintComponent(g);
                if (getPlaceholder() != null && getText().isEmpty() && (isPaintingOnFocus() || !isFocusOwner())) {
                    try {
                        final Rectangle rect = getUI().modelToView(this, 0);
                        final Insets insets = getInsets();
                        g.setFont(getFont());
                        g.setColor(getPlaceholderColor() == null ? getForeground() : getPlaceholderColor());
                        ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                        g.drawString(getPlaceholder(), rect.x, getHeight() - insets.top - insets.bottom - rect.y);
                    } catch (final BadLocationException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        
            private class RepaintFocusListener implements FocusListener {
                @Override
                public void focusGained(final FocusEvent e) {
                    repaint();
                }
        
                @Override
                public void focusLost(final FocusEvent e) {
                    repaint();
                }
            }
        }
        

        您可以选择文本和颜色以及是否应该绘制,即使文本字段有焦点。

        关键部分是覆盖paintComponent(Graphics)

        【讨论】:

          【解决方案5】:

          要实现这样的目标,您通常需要创建特定类型的event listener。在您的情况下,需要在鼠标事件上触发所需的操作 - 因此 MouseAdapter 事件侦听器似乎很合适(乍一看)。使用MouseAdapter 抽象类,您需要扩展它并覆盖必要的方法(有关可用方法的完整列表,请参阅here)。

          实现这一点的最短方法是通过anonymous class 声明,如下所示:

          cruiseSel.addMouseListener(new MouseAdapter(){
              @Override
              public void mouseClicked(MouseEvent e){
                  cruiseSel.setText("");
              }
          });
          

          (但是,如果您需要覆盖多个方法或触发的逻辑感觉足够复杂,则最好创建一个单独的侦听器类。)

          编辑:或者,正如@HovercraftFullOfEels 在评论部分指出的那样,以相同的方式应用FocusAdapter 类(参见here)可能更明智:

          cruiseSel.addFocusListener(new FocusAdapter(){
              @Override
              public void focusGained(FocusEvent e){
                  cruiseSel.setText("");
              }
          });
          

          第一个解决方案的问题在于它只关注文本字段上的实际鼠标点击,而后者则监听任何类型的焦点增益。因此,当使用 TAB 键在文本字段之间切换时,只有第二种解决方案才能正确执行。

          【讨论】:

          • 当用户进入该字段时,这将失败。没有。
          • @HovercraftFullOfEels:是的,感谢您指出这一点。我已经有一段时间没有使用 Swing 库了,所以你提到的问题并没有立即浮现在脑海中。我已修改我的答案以反映您的建议。
          • 这种方法的问题是你总是在组件获得焦点时清除文本。您无法确定文本是“提示”还是“用户输入的文本”。
          • @camickr:没错,这意味着您还需要一个硬编码的默认字符串来检查每次触发事件时的情况,这可能有很多原因(i18n, “如果默认字符串是我想输入的怎么办?!”等)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-09-16
          • 2011-06-19
          • 1970-01-01
          • 1970-01-01
          • 2012-10-28
          • 2013-01-25
          • 2014-06-18
          相关资源
          最近更新 更多