2009-11-15 2 views
36

Я хотел бы добавить значение подсказки к моему JTextField. Он должен выглядеть как рендеринг Firefox <input type="text" title="bla">. Это создает поле редактирования с текстом «bla» в фоновом режиме. Если текстовое поле имеет фокус, заголовок-текст исчезает и снова появляется, если пользователь покидает поле редактирования без текста.Java JTextField с подсказкой ввода

Есть ли (бесплатный) компонент поворота, который делает что-то вроде этого?

+0

Я нашел свинг ошибка ТЕЗИСОВ ДОКЛАДА t об этом на https://swingx.dev.java.net/issues/show_bug.cgi?id=306 Спасибо за помощь. – Wienczny

+0

2018 и не однострочное решение.Smh –

ответ

16

Взгляните на этот: http://code.google.com/p/xswingx/

Это не очень трудно реализовать самостоятельно, кстати. Несколько слушателей и пользовательский рендерер и вуаля.

3

Для любого компонента Swing (то есть всего, что расширяет JComponent) вы можете вызвать метод setToolTipText (String).

Для получения дополнительной информации, ссылки на следующие ссылки:

+5

Я думаю, что он не говорит о подсказке, он хочет что-то вроде «Напечатайте здесь, чтобы искать» серый текст, который исчезает, когда вы начинаете вводить – Dmitry

+0

Хм, возможно, вы правы, но это соответствует HTML, который он предоставил. OP .., если вы хотите очистить/установить текст по умолчанию, когда ввод сфокусирован/размыт, посмотрите в FocusListener: http://java.sun.com/docs/books/tutorial/uiswing/events/focuslistener.html – Matt

+0

Дмитрий прав. Спасибо за вашу помощь. – Wienczny

50

Вы можете создать свой собственный:

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

Если вы все еще на Java 1.5, замените this.getText().isEmpty() с this.getText().length() == 0.

+0

Это решение тоже приятно. Вам придется перегружать getText() и фильтровать текст подсказки. – Wienczny

+1

Я предпочел бы использовать флаг в getText(), который указывает, отображается ли подсказка или нет.В противном случае, если пользователь вводит текст подсказки, getText() также возвращает пустую строку. –

+0

@MichaelJess, да, вы правы. Я отредактировал мой пример, чтобы вместо этого добавить логический флаг. –

13

Вот один экземпляр класса/паста решение:

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).

+0

Как можно сделать так, чтобы подсказка была выделена курсивом, но пользователь введенного текста нет? –

+0

В 'paintSafely()' вам нужно будет вызвать 'setFont (fontHint)' или 'setFont (fontOriginal)' в соответствии с 'getText(). IsEmpty()', где 'fontHint' был бы получен из исходный 'getFont()' в конструкторе. Мне также пришлось переопределить 'setFont()' для его регенерации: 'fontOriginal = getFont(); hintFont = new Font (fontOriginal.getName(), fontOriginal.getStyle() | Font.ITALIC, fontOriginal.getSize()); ' Обратите внимание, что я не использовал' font.deriveFont() ', потому что кажется, что он ест много памяти и никогда не возвращает его ... – Matthieu

+0

работает как очарование, спасибо! – patrickdamery

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"); 
9

Вот простой способ, который хорошо выглядит в любом 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; 
} 
+1

Мне это нравится, потому что способность подсказки становится функцией 'JTextField', а не внешним надстройкой (что имеет место для большинства других решений, которые я видел). Но, возможно, вам следует объяснить немного больше, что делает код и почему он работает. Есть ли побочные эффекты ? Какие гарантии он нарисовал бы подсказку в шрифте, который использует поле? – peterh

3

есть взгляд на WebLookAndFeel на https://github.com/mgarin/weblaf/

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); 
+0

Есть много других функций, поддерживаемых WebLAF – user2473015

Смежные вопросы