Swing/GhostText の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/GhostText へ行く。
- Swing/GhostText の差分を削除
--- category: swing folder: GhostText title: JTextFieldにフォーカスと文字列が無い場合の表示 tags: [JTextField, Focus, FocusListener] author: aterai pubdate: 2005-11-07T16:50:50+09:00 description: JTextFieldにフォーカスが無く文字列が空の場合、薄い色でその説明を表示します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTNY3BG1nI/AAAAAAAAAas/YJB5L9kNK-c/s800/GhostText.png --- * 概要 [#summary] `JTextField`にフォーカスが無く文字列が空の場合、薄い色でその説明を表示します。 #download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTNY3BG1nI/AAAAAAAAAas/YJB5L9kNK-c/s800/GhostText.png) * サンプルコード [#sourcecode] #code(link){{ class PlaceholderFocusListener implements FocusListener { private static final Color INACTIVE = UIManager.getColor("TextField.inactiveForeground"); private final String hintMessage; public PlaceholderFocusListener(JTextComponent tf) { hintMessage = tf.getText(); tf.setForeground(INACTIVE); } @Override public void focusGained(FocusEvent e) { JTextComponent tf = (JTextComponent) e.getComponent(); if (hintMessage.equals(tf.getText()) && INACTIVE.equals(tf.getForeground())) { tf.setForeground(UIManager.getColor("TextField.foreground")); tf.setText(""); } } @Override public void focusLost(FocusEvent e) { JTextComponent tf = (JTextComponent) e.getComponent(); if ("".equals(tf.getText().trim())) { tf.setForeground(INACTIVE); tf.setText(hintMessage); } } } }} * 解説 [#explanation] 上記のサンプルでは、`JTextField`からフォーカスが失われた時にまだ何も入力されていない場合はその`JTextField`の説明などを透かし文字として薄く表示しています。 ---- - `JDK 1.7.0`以上の場合は`JLayer`を使用して同様にヒント文字列を描画可能 - `Java 1.7.0`以上の場合`JLayer`を使用して同様にヒント文字列を描画可能 #code{{ class PlaceholderLayerUI extends LayerUI<JTextComponent> { private static final Color INACTIVE = UIManager.getColor("TextField.inactiveForeground"); private final JLabel hint; public PlaceholderLayerUI(String hintMessage) { super(); this.hint = new JLabel(hintMessage); hint.setForeground(INACTIVE); } @Override public void paint(Graphics g, JComponent c) { super.paint(g, c); if (c instanceof JLayer) { JLayer jlayer = (JLayer) c; JTextComponent tc = (JTextComponent) jlayer.getView(); if (tc.getText().length() == 0 && !tc.hasFocus()) { Graphics2D g2 = (Graphics2D) g.create(); g2.setPaint(INACTIVE); Insets i = tc.getInsets(); Dimension d = hint.getPreferredSize(); SwingUtilities.paintComponent(g2, hint, tc, i.left, i.top, d.width, d.height); g2.dispose(); } } } @Override public void installUI(JComponent c) { super.installUI(c); if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask(AWTEvent.FOCUS_EVENT_MASK); } } @Override public void uninstallUI(JComponent c) { super.uninstallUI(c); if (c instanceof JLayer) { ((JLayer) c).setLayerEventMask(0); } } @Override public void processFocusEvent(FocusEvent e, JLayer<? extends JTextComponent> l) { l.getView().repaint(); } } }} * 参考リンク [#reference] - [[JTextFieldに透かし画像を表示する>Swing/WatermarkInTextField]] - [[JPasswordFieldにヒント文字列を描画する>Swing/InputHintPasswordField]] -- `JPasswordField`の場合、`setText(String)`は使用できないので、透かし画像と同じ要領で`paintComponent`をオーバーライドして文字列を描画 -- `JPasswordField`の場合`setText(String)`は使用できないので透かし画像と同じ要領で`paintComponent`をオーバーライドして文字列を描画 - [[JComboBoxでアイテムが選択されていない場合のプレースホルダ文字列を設定する>Swing/ComboBoxPlaceholder]] * コメント [#comment] #comment - タイトルを変更メモ: `Input Hint`、`Placeholder`、`Watermark` ... -- &user(aterai); &new{2009-11-17 (火) 15:48:18}; - `LayerUI#paint(...)`中で子コンポーネントの`repaint()`を呼び出して再描画が無限ループするバグを修正。 -- &user(aterai); &new{2014-07-26 (土) 04:51:11}; #comment