Swing/ShowHidePasswordField の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ShowHidePasswordField へ行く。
- Swing/ShowHidePasswordField の差分を削除
--- category: swing folder: ShowHidePasswordField title: JPasswordFieldでパスワードを可視化する tags: [JPasswordField, JCheckBox, JToggleButton, OverlayLayout, CardLayout] author: aterai pubdate: 2015-01-05T00:29:05+09:00 description: JPasswordFieldに入力したパスワードの表示・非表示を切り替えるためのボタンを作成し、これを入力欄などに配置します。 image: https://lh4.googleusercontent.com/-zXk3TZfF_v4/VPXFdo3UBzI/AAAAAAAANzU/VfiEUdm-aUI/s800/ShowHidePasswordField.png hreflang: href: https://java-swing-tips.blogspot.com/2015/01/showhide-passwordfield-using-cardlayout.html lang: en --- * Summary [#summary] `JPasswordField`に入力したパスワードの表示・非表示を切り替えるためのボタンを作成し、これを入力欄などに配置します。 #download(https://lh4.googleusercontent.com/-zXk3TZfF_v4/VPXFdo3UBzI/AAAAAAAANzU/VfiEUdm-aUI/s800/ShowHidePasswordField.png) * Source Code Examples [#sourcecode] #code(link){{ JPasswordField pf = new JPasswordField(24); pf.setText("abcdefghijklmn"); pf.setAlignmentX(Component.RIGHT_ALIGNMENT); AbstractDocument doc = (AbstractDocument) pf.getDocument(); doc.setDocumentFilter(new ASCIIOnlyDocumentFilter()); AbstractButton b = new JToggleButton(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { AbstractButton c = (AbstractButton) e.getSource(); pf.setEchoChar(c.isSelected() ? '\u0000' : (Character) UIManager.get("PasswordField.echoChar")); } }); b.setFocusable(false); b.setOpaque(false); b.setContentAreaFilled(false); b.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 4)); b.setAlignmentX(Component.RIGHT_ALIGNMENT); b.setAlignmentY(Component.CENTER_ALIGNMENT); b.setIcon(new EyeIcon(Color.BLUE)); b.setRolloverIcon(new EyeIcon(Color.DARK_GRAY)); b.setSelectedIcon(new EyeIcon(Color.BLUE)); b.setRolloverSelectedIcon(new EyeIcon(Color.BLUE)); b.setToolTipText("show/hide passwords"); JPanel panel = new JPanel() { @Override public boolean isOptimizedDrawingEnabled() { return false; } }; panel.setLayout(new OverlayLayout(panel)); panel.add(b); panel.add(pf); }} * Explanation [#explanation] 上記のサンプルでは、`JPasswordField#setEchoChar(...)`メソッドの値に`\u0000`(`0`)を設定して入力したパスワードを可視状態に切り替えるためのボタンを追加しています。 - `BorderLayout + JCheckBox`: -- `BorderLayout`で`JPasswordField`の下にパスワード表示非表示切り替え用の`JCheckBox`を配置 - `OverlayLayout + JToggleButton`: -- `OverlayLayout`で`JPasswordField`内の右端にパスワード表示非表示切り替え用の`JToggleButton`を配置 -- `JPasswordField`と`JToggleButton`を配置する`JPanel`に`OverlayLayout`を設定し、マウスカーソルでこのレイアウトの`z`軸が入れ替わらないように`JPanel#isOptimizedDrawingEnabled()`が常に`false`を返すようオーバーライド - `CardLayout + JTextField(can copy) + ...`: -- 同じ`Document`を使用する`JPasswordField`と`JTextField`を`CardLayout`を設定した`JPanel`を作成 -- `OverlayLayout`を設定した`JPanel`に上記の`JPanel`と`JToggleButton`を配置し、`JPasswordField`などの内部右端にボタンが表示されるように設定 -- `JTextField`をそのまま使用しているので表示中の文字列を選択してコピー可能 #code{{ JPasswordField pf3 = new JPasswordField(24); pf3.setText("abcdefghijklmn"); AbstractDocument doc = (AbstractDocument) pf3.getDocument(); JTextField tf3 = new JTextField(24); tf3.setFont(FONT); tf3.enableInputMethods(false); tf3.setDocument(doc); final CardLayout cardLayout = new CardLayout(); final JPanel p3 = new JPanel(cardLayout); p3.setAlignmentX(Component.RIGHT_ALIGNMENT); p3.add(pf3, PasswordField.HIDE.toString()); p3.add(tf3, PasswordField.SHOW.toString()); AbstractButton b3 = new JToggleButton(new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { AbstractButton c = (AbstractButton) e.getSource(); PasswordField s = c.isSelected() ? PasswordField.SHOW : PasswordField.HIDE; cardLayout.show(p3, s.toString()); } }); }} - `press and hold down the mouse button`: -- `OverlayLayout`で`JPasswordField`内の右端にパスワード表示非表示切り替え用の`JButton`を配置 -- この`JButton`に`MouseListener`を追加してマウスでクリックしている間はパスワードを表示するように設定 #code{{ b4.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { pf4.setEchoChar('\u0000'); } @Override public void mouseReleased(MouseEvent e) { pf4.setEchoChar((Character) UIManager.get("PasswordField.echoChar")); } }); }} ---- - `passwordField.setEchoChar((char) 0);`を使用するサンプルを追加 -- [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JPasswordField.html#setEchoChar-char- JPasswordField#setEchoChar(...) (Java Platform SE 8)]に「値`0`に設定すると標準の`JTextField`の動作と同様にテキストが入力したとおりに表示されます。」とあるように`passwordField.setEchoChar((char) 0);`とすればパスワード文字列の表示が可能 -- `CardLayout`を使って`JTextField`を表示する方法は一旦削除したが、表示中のパスワードをコピー可能なので残しておくことにした --- [[JPasswordFieldでCutとCopyを可能にする>Swing/PasswordFieldCutCopyAllowed]] - ボタンをクリックしている間だけパスワードを表示するサンプルを追加 * Reference [#reference] - [https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/JPasswordField.html#setEchoChar-char- JPasswordField#setEchoChar(...) (Java Platform SE 8)] - [[JPasswordFieldのエコー文字を変更>Swing/PasswordView]] - [[JPasswordFieldでPINコード入力欄を作成する>Swing/PinCodeInputField]] * コメント [#comment] * Comment [#comment] #comment #comment