Swing/DisabledOkButtonOptionPane の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DisabledOkButtonOptionPane へ行く。
- Swing/DisabledOkButtonOptionPane の差分を削除
--- category: swing folder: DisabledOkButtonOptionPane title: JOptionPaneのOKボタンを文字列が入力されるまで選択不可に設定する tags: [JOptionPane, DefaultButton, JTextField, DocumentListener] author: aterai pubdate: 2020-04-13T00:57:30+09:00 description: JOptionPaneのConfirmDialogに表示されるOKボタンを文字列が入力されるまで選択不可に設定します。 image: https://drive.google.com/uc?id=1blPT1pPi2dsuRd88JceWb8mITDHT9Yd1 hreflang: href: https://java-swing-tips.blogspot.com/2020/05/disable-joptionpane-ok-button-until.html lang: en --- * 概要 [#summary] `JOptionPane`の`ConfirmDialog`に表示される`OK`ボタンを文字列が入力されるまで選択不可に設定します。 #download(https://drive.google.com/uc?id=1blPT1pPi2dsuRd88JceWb8mITDHT9Yd1) * サンプルコード [#sourcecode] #code(link){{ JPanel panel2 = new JPanel(new GridLayout(2, 1)); JTextField field2 = new JTextField(); Border enabledBorder = field2.getBorder(); Insets i = enabledBorder.getBorderInsets(field2); Border disabledBorder = BorderFactory.createCompoundBorder( BorderFactory.createLineBorder(Color.RED), BorderFactory.createEmptyBorder(i.top - 1, i.left - 1, i.bottom - 1, i.right - 1)); String disabledMessage = "Text is required to create ..."; JLabel label2 = new JLabel(" "); label2.setForeground(Color.RED); panel2.add(field2); panel2.add(label2); if (field2.getText().isEmpty()) { field2.setBorder(disabledBorder); label2.setText(disabledMessage); } field2.addHierarchyListener(e -> { Component c = e.getComponent(); if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && c.isShowing()) { EventQueue.invokeLater(c::requestFocusInWindow); } }); field2.getDocument().addDocumentListener(new DocumentListener() { private void update() { boolean verified = !field2.getText().isEmpty(); JButton b = field2.getRootPane().getDefaultButton(); if (verified) { b.setEnabled(true); field2.setBorder(enabledBorder); label2.setText(" "); } else { b.setEnabled(false); field2.setBorder(disabledBorder); label2.setText(disabledMessage); } } @Override public void insertUpdate(DocumentEvent e) { update(); } @Override public void removeUpdate(DocumentEvent e) { update(); } @Override public void changedUpdate(DocumentEvent e) { update(); } }); JButton button2 = new JButton("show"); button2.addActionListener(e -> { Component p2 = log.getRootPane(); EventQueue.invokeLater(() -> { JButton b = field2.getRootPane().getDefaultButton(); if (b != null && field2.getText().isEmpty()) { b.setEnabled(false); } }); int ret = JOptionPane.showConfirmDialog( p2, panel2, "Input text", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); if (ret == JOptionPane.OK_OPTION) { log.setText(field2.getText()); } }); }} * 解説 [#explanation] - 文字列入力用の`JTextField`を作成 - `HierarchyListener`を`JTextField`に追加し、`ConfirmDialog`が開いたときの初期フォーカスをデフォルトボタンからこの`JTextField`に移動 -- [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]] - `DocumentListener`を`JTextField`のドキュメントに追加し、`JTextField`に入力があれば`OK`ボタンの選択可・不可を切り替える - `DocumentListener`を`JTextField`のドキュメントに追加して`JTextField`に入力があれば`OK`ボタンの選択可・不可を切り替える -- `ConfirmDialog`の`OK`ボタンは`JTextField#getRootPane()#getDefaultButton()`などで取得可能 -- このサンプルでは`JTextField`の`Border`なども切り替えている - `JOptionPane.showConfirmDialog(...)`のメッセージに`JTextField`を含むコンポーネントを設定して`ConfirmDialog`を開く * 参考リンク [#reference] - [[JOptionPaneのデフォルトフォーカス>Swing/OptionPaneDefaultFocus]] * コメント [#comment] #comment #comment