制作带有消失文本的 JTextField

Making a JTextField with Vanishing Text

我知道您可以事先将文本输入到 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:"。然后必须手动删除此文本以清除文本字段。

Is there a way to input text in an JTextField, so once the GUI opens, the text will be displayed, but when the JTextField is selected to input manual text, the text vanishes?

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

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

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

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

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

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

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

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

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

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

您可以使用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);
            }
        });
    }

}

查看 Text Prompt

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

您要找的是占位符。我之前写过这个 class:

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)