47

にヒント値を追加したいと思いjavax.swing.JTextFieldます。のFirefoxレンダリングのように見えるはずです<input type="text" title="bla">。これにより、テキスト「bla」が背景にある編集フィールドが作成されます。テキストボックスにフォーカスがある場合、タイトルテキストは消え、ユーザーがテキストなしで編集ボックスを離れると、テキストが再び表示されます。

このようなことをする(無料の)スイングコンポーネントはありますか?

4

9 に答える 9

60

あなたはあなた自身を作成することができます:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.*;

public class Main {

  public static void main(String[] args) {

    final JFrame frame = new JFrame();

    frame.setLayout(new BorderLayout());

    final JTextField textFieldA = new HintTextField("A hint here");
    final JTextField textFieldB = new HintTextField("Another hint here");

    frame.add(textFieldA, BorderLayout.NORTH);
    frame.add(textFieldB, BorderLayout.CENTER);
    JButton btnGetText = new JButton("Get text");

    btnGetText.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        String message = String.format("textFieldA='%s', textFieldB='%s'",
            textFieldA.getText(), textFieldB.getText());
        JOptionPane.showMessageDialog(frame, message);
      }
    });

    frame.add(btnGetText, BorderLayout.SOUTH);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.pack();
  }
}

class HintTextField extends JTextField implements FocusListener {

  private final String hint;
  private boolean showingHint;

  public HintTextField(final String hint) {
    super(hint);
    this.hint = hint;
    this.showingHint = true;
    super.addFocusListener(this);
  }

  @Override
  public void focusGained(FocusEvent e) {
    if(this.getText().isEmpty()) {
      super.setText("");
      showingHint = false;
    }
  }
  @Override
  public void focusLost(FocusEvent e) {
    if(this.getText().isEmpty()) {
      super.setText(hint);
      showingHint = true;
    }
  }

  @Override
  public String getText() {
    return showingHint ? "" : super.getText();
  }
}

まだJava1.5を使用している場合は、をに置き換えてthis.getText().isEmpty()くださいthis.getText().length() == 0

于 2009-11-15T22:11:59.290 に答える
21

これは、どのL&Fでも見栄えのする簡単な方法です。

public class HintTextField extends JTextField {
    public HintTextField(String hint) {
        _hint = hint;
    }
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        if (getText().length() == 0) {
            int h = getHeight();
            ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            Insets ins = getInsets();
            FontMetrics fm = g.getFontMetrics();
            int c0 = getBackground().getRGB();
            int c1 = getForeground().getRGB();
            int m = 0xfefefefe;
            int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1);
            g.setColor(new Color(c2, true));
            g.drawString(_hint, ins.left, h / 2 + fm.getAscent() / 2 - 2);
        }
    }
    private final String _hint;
}
于 2014-07-04T10:01:07.430 に答える
17

これが単一クラスのコピー/貼り付けソリューションです。

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.JTextComponent;


public class HintTextFieldUI extends BasicTextFieldUI implements FocusListener {

    private String hint;
    private boolean hideOnFocus;
    private Color color;

    public Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
        repaint();
    }

    private void repaint() {
        if(getComponent() != null) {
            getComponent().repaint();           
        }
    }

    public boolean isHideOnFocus() {
        return hideOnFocus;
    }

    public void setHideOnFocus(boolean hideOnFocus) {
        this.hideOnFocus = hideOnFocus;
        repaint();
    }

    public String getHint() {
        return hint;
    }

    public void setHint(String hint) {
        this.hint = hint;
        repaint();
    }
    public HintTextFieldUI(String hint) {
        this(hint,false);
    }

    public HintTextFieldUI(String hint, boolean hideOnFocus) {
        this(hint,hideOnFocus, null);
    }

    public HintTextFieldUI(String hint, boolean hideOnFocus, Color color) {
        this.hint = hint;
        this.hideOnFocus = hideOnFocus;
        this.color = color;
    }

    @Override
    protected void paintSafely(Graphics g) {
        super.paintSafely(g);
        JTextComponent comp = getComponent();
        if(hint!=null && comp.getText().length() == 0 && (!(hideOnFocus && comp.hasFocus()))){
            if(color != null) {
                g.setColor(color);
            } else {
                g.setColor(comp.getForeground().brighter().brighter().brighter());              
            }
            int padding = (comp.getHeight() - comp.getFont().getSize())/2;
            g.drawString(hint, 2, comp.getHeight()-padding-1);          
        }
    }

    @Override
    public void focusGained(FocusEvent e) {
        if(hideOnFocus) repaint();

    }

    @Override
    public void focusLost(FocusEvent e) {
        if(hideOnFocus) repaint();
    }
    @Override
    protected void installListeners() {
        super.installListeners();
        getComponent().addFocusListener(this);
    }
    @Override
    protected void uninstallListeners() {
        super.uninstallListeners();
        getComponent().removeFocusListener(this);
    }
}

次のように使用します。

TextField field = new JTextField();
field.setUI(new HintTextFieldUI("Search", true));

で発生していることに注意してくださいprotected void paintSafely(Graphics g)

于 2011-02-10T21:19:59.330 に答える
14

これを見てください:http ://code.google.com/p/xswingx/

ところで、自分で実装するのはそれほど難しいことではありません。リスナーのカップルとカスタムレンダラーと出来上がり。

于 2009-11-15T22:03:28.943 に答える
3

Swingコンポーネント(つまり、JComponentを拡張するもの)の場合は、setToolTipText(String)メソッドを呼び出すことができます。

詳細については、次のリンクを参照してください。

于 2009-11-15T22:02:02.363 に答える
3

https://github.com/mgarin/weblaf/でWebLookAndFeelをご覧ください

WebTextField txtName = new com.alee.laf.text.WebTextField();

txtName.setHideInputPromptOnFocus(false);

txtName.setInputPrompt("Name");

txtName.setInputPromptFont(new java.awt.Font("Ubuntu", 0, 18));

txtName.setInputPromptForeground(new java.awt.Color(102, 102, 102));

txtName.setInputPromptPosition(0);
于 2015-06-11T13:46:00.290 に答える
2

それでも解決策を探している場合は、参考のために他の回答(Bart Kiersとculmat)を組み合わせたものを次に示します。

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;


public class HintTextField extends JTextField implements FocusListener
{

    private String hint;

    public HintTextField ()
    {
        this("");
    }

    public HintTextField(final String hint)
    {
        setHint(hint);
        super.addFocusListener(this);
    }

    public void setHint(String hint)
    {
        this.hint = hint;
        setUI(new HintTextFieldUI(hint, true));
        //setText(this.hint);
    }


    public void focusGained(FocusEvent e)
    {
        if(this.getText().length() == 0)
        {
            super.setText("");
        }
    }

    public void focusLost(FocusEvent e)
    {
        if(this.getText().length() == 0)
        {
            setHint(hint);
        }
    }

    public String getText()
    {
        String typed = super.getText();
        return typed.equals(hint)?"":typed;
    }
}

class HintTextFieldUI extends javax.swing.plaf.basic.BasicTextFieldUI implements FocusListener
{

    private String hint;
    private boolean hideOnFocus;
    private Color color;

    public Color getColor()
    {
        return color;
    }

    public void setColor(Color color)
    {
        this.color = color;
        repaint();
    }

    private void repaint()
    {
        if(getComponent() != null)
        {
            getComponent().repaint();
        }
    }

    public boolean isHideOnFocus()
    {
        return hideOnFocus;
    }

    public void setHideOnFocus(boolean hideOnFocus)
    {
        this.hideOnFocus = hideOnFocus;
        repaint();
    }

    public String getHint()
    {
        return hint;
    }

    public void setHint(String hint)
    {
        this.hint = hint;
        repaint();
    }

    public HintTextFieldUI(String hint)
    {
        this(hint, false);
    }

    public HintTextFieldUI(String hint, boolean hideOnFocus)
    {
        this(hint, hideOnFocus, null);
    }

    public HintTextFieldUI(String hint, boolean hideOnFocus, Color color)
    {
        this.hint = hint;
        this.hideOnFocus = hideOnFocus;
        this.color = color;
    }


    protected void paintSafely(Graphics g)
    {
        super.paintSafely(g);
        JTextComponent comp = getComponent();
        if(hint != null && comp.getText().length() == 0 && (!(hideOnFocus && comp.hasFocus())))
        {
            if(color != null)
            {
                g.setColor(color);
            }
            else
            {
                g.setColor(Color.gray);
            }
            int padding = (comp.getHeight() - comp.getFont().getSize()) / 2;
            g.drawString(hint, 5, comp.getHeight() - padding - 1);
        }
    }


    public void focusGained(FocusEvent e)
    {
        if(hideOnFocus) repaint();

    }


    public void focusLost(FocusEvent e)
    {
        if(hideOnFocus) repaint();
    }

    protected void installListeners()
    {
        super.installListeners();
        getComponent().addFocusListener(this);
    }

    protected void uninstallListeners()
    {
        super.uninstallListeners();
        getComponent().removeFocusListener(this);
    }
}



Usage:
HintTextField field = new HintTextField();
field.setHint("Here's a hint");
于 2012-05-22T15:04:00.417 に答える
2

これは、フォーカスリスナーを使用してテキストフィールドのコンテンツを更新することで実現できます。

クラスにフォーカスリスナーインターフェイスを実装させます。

class YourClass implements FocusListener

フィールドを空白にするフォーカスが取得されたときにキャッチするメソッドを追加します。

public void focusGained(FocusEvent e) {
    if(JTextField1.getText().equals("Username")) {
        JTextField1.setText("");
    }
}

フィールドが空白の場合にデフォルトのエントリを再表示するために、フォーカスが失われたときにキャッチするメソッドを追加します。

public void focusLost(FocusEvent e) {
    if(JTextField1.getText().equals("")) {
        JTextField1.setText("Username");
        // you should prevent the form from being processed in this state
        // as it will literally contain "Username" for the username
    }
}

クラスをテキストフィールドのフォーカスリスナーとして登録します。

textField.addFocusListener(this);

詳細については、Javaチュートリアルでフォーカスリスナーを作成する方法を参照してください。

于 2019-03-07T14:24:37.890 に答える
0

これは、AdamGawne-Cainの以前の投稿に基づいた完全に機能する例です。彼の解決策は単純で、実際には非常にうまく機能します。

複数のフィールドのグリッドで次のテキストを使用しました。

H__|__WWW__+__XXXX__+__WWW__|__H

これにより、ヒント付きテキストのx/y配置を簡単に確認できます。

いくつかの観察事項:
-解決策はいくつもありますが、多くは表面的にしか機能しないか、バグがあり
ます-sun.tools.jconsole.ThreadTab.PromptingTextFieldは単純な解決策ですが、フィールドの場合にのみプロンプトテキストが表示されますフォーカスがなく、プライベートですが、少しカットアンドペーストしても修正されません。

以下は、JDK8以降で動作します。

import java.awt.*;
import java.util.stream.*;
import javax.swing.*;
/**
 * @author DaveTheDane, based on a suggestion from Adam Gawne-Cain
 */
public final class JTextFieldPromptExample extends JFrame {

    private static JTextField newPromptedJTextField (final String text, final String prompt) {

        final String promptPossiblyNullButNeverWhitespace = prompt == null || prompt.trim().isEmpty()  ?  null  :  prompt;

        return new JTextField(text) {
            @Override
            public void paintComponent(final Graphics    USE_g2d_INSTEAD) {
                final Graphics2D     g2d =  (Graphics2D) USE_g2d_INSTEAD;

                super.paintComponent(g2d);

//              System.out.println("Paint.: " + g2d);

                if (getText().isEmpty()
                &&  promptPossiblyNullButNeverWhitespace != null) {
                    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

                    final Insets      ins = getInsets();
                    final FontMetrics fm  = g2d.getFontMetrics();

                    final int cB = getBackground().getRGB();
                    final int cF = getForeground().getRGB();
                    final int m  = 0xfefefefe;
                    final int c2 = ((cB & m) >>> 1) + ((cF & m) >>> 1); // "for X in (A, R, G, B) {Xnew = (Xb + Xf) / 2}"
                    /*
                     * The hint text color should be halfway between the foreground and background colors so it is always gently visible.
                     * The variables c0,c1,m,c2 calculate the halfway color's ARGB fields simultaneously without overflowing 8 bits.
                     * Swing sets the Graphics' font to match the JTextField's font property before calling the "paint" method,
                     * so the hint font will match the JTextField's font.
                     * Don't think there are any side effects because Swing discards the Graphics after painting.
                     * Adam Gawne-Cain, Aug 6 2019 at 15:55
                     */
                    g2d.setColor(new Color(c2, true));
                    g2d.drawString(promptPossiblyNullButNeverWhitespace, ins.left, getHeight() - fm.getDescent() - ins.bottom);
                    /*
                     * y Coordinate based on Descent & Bottom-inset seems to align Text spot-on.
                     * DaveTheDane, Apr 10 2020
                     */
                }
            }
        };
    }

    private static final GridBagConstraints GBC_LEFT  = new GridBagConstraints();
    private static final GridBagConstraints GBC_RIGHT = new GridBagConstraints();
    /**/    static {
        GBC_LEFT .anchor    = GridBagConstraints.LINE_START;
        GBC_LEFT .fill      = GridBagConstraints.HORIZONTAL;
        GBC_LEFT .insets    = new Insets(8, 8, 0, 0);

        GBC_RIGHT.gridwidth = GridBagConstraints.REMAINDER;
        GBC_RIGHT.fill      = GridBagConstraints.HORIZONTAL;
        GBC_RIGHT.insets    = new Insets(8, 8, 0, 8);
    }

    private <C extends Component> C addLeft (final C component) {
        this    .add           (component);
        this.gbl.setConstraints(component, GBC_LEFT);
        return                  component;
    }
    private <C extends Component> C addRight(final C component) {
        this    .add           (component);
        this.gbl.setConstraints(component, GBC_RIGHT);
        return                  component;
    }

    private static final String ALIGN = "H__|__WWW__+__XXXX__+__WWW__|__H";

    private final GridBagLayout gbl = new GridBagLayout();

    public JTextFieldPromptExample(final String title) {
        super(title);
        this.setLayout(gbl);

        final java.util.List<JTextField> texts = Stream.of(
                addLeft (newPromptedJTextField(ALIGN + ' ' + "Top-Left"    , ALIGN)),
                addRight(newPromptedJTextField(ALIGN + ' ' + "Top-Right"   , ALIGN)),

                addLeft (newPromptedJTextField(ALIGN + ' ' + "Middle-Left" , ALIGN)),
                addRight(newPromptedJTextField(                       null , ALIGN)),

                addLeft (new        JTextField("x"        )),
                addRight(newPromptedJTextField("x",   ""  )),

                addLeft (new        JTextField(null       )),
                addRight(newPromptedJTextField(null,  null)),

                addLeft (newPromptedJTextField(ALIGN + ' ' + "Bottom-Left" , ALIGN)),
                addRight(newPromptedJTextField(ALIGN + ' ' + "Bottom-Right", ALIGN)) ).collect(Collectors.toList());

        final JButton button = addRight(new JButton("Get texts"));
        /**/                   addRight(Box.createVerticalStrut(0)); // 1 last time forces bottom inset

        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.setPreferredSize(new Dimension(740, 260));
        this.pack();
        this.setResizable(false);
        this.setVisible(true);

        button.addActionListener(e -> {
            texts.forEach(text -> System.out.println("Text..: " + text.getText()));
        });
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> new JTextFieldPromptExample("JTextField with Prompt"));
    }
}
于 2020-04-10T12:41:08.103 に答える