Swing/TriStateCheckBox のバックアップの現在との差分(No.11)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/TriStateCheckBox へ行く。
- 1 (2011-12-12 (月) 15:00:11)
- 2 (2011-12-12 (月) 21:28:18)
- 3 (2012-03-08 (木) 12:43:16)
- 4 (2012-12-14 (金) 13:45:50)
- 5 (2013-08-17 (土) 15:40:04)
- 6 (2014-11-22 (土) 03:59:58)
- 7 (2015-01-22 (木) 21:07:06)
- 8 (2016-04-27 (水) 18:09:24)
- 9 (2017-04-07 (金) 13:51:51)
- 10 (2017-08-01 (火) 14:19:18)
- 11 (2018-08-02 (木) 15:33:10)
- 12 (2021-12-24 (金) 12:40:59)
- 13 (2023-10-23 (月) 20:08:58)
- 14 (2023-11-03 (金) 22:12:26)
- 15 (2023-11-15 (水) 09:33:24)
- 追加された行はこの色です。
- 削除された行はこの色です。
--- category: swing folder: TriStateCheckBox title: JCheckBoxに不定状態のアイコンを追加する tags: [JCheckBox, Icon, UIManager, JTableHeader, JTable] author: aterai pubdate: 2011-12-12T15:00:11+09:00 description: JCheckBoxの選択状態、非選択状態に加えて、不定状態を表すアイコンを追加します。 description: JCheckBoxの選択状態、非選択状態に加えて不定状態を表すアイコンを追加します。 image: https://lh6.googleusercontent.com/-Rs-vnlD35Cg/TuTNCuEvU_I/AAAAAAAABF4/IzDezx4Rq8M/s800/TriStateCheckBox.png --- * 概要 [#summary] `JCheckBox`の選択状態、非選択状態に加えて、不定状態を表すアイコンを追加します。 `JCheckBox`の選択状態、非選択状態に加えて不定状態を表すアイコンを追加します。 #download(https://lh6.googleusercontent.com/-Rs-vnlD35Cg/TuTNCuEvU_I/AAAAAAAABF4/IzDezx4Rq8M/s800/TriStateCheckBox.png) * サンプルコード [#sourcecode] #code(link){{ JCheckBox checkBox = new JCheckBox("TriState JCheckBox") { protected TriStateActionListener listener = null; class TriStateActionListener implements ActionListener { protected Icon icon; public void setIcon(Icon icon) { this.icon = icon; class TriStateCheckBox extends JCheckBox { private transient TriStateActionListener listener; private transient Icon icon; protected TriStateCheckBox(String title) { super(title); } public void updateStatus(Status s) { switch (s) { case SELECTED: setSelected(true); setIcon(null); break; case DESELECTED: setSelected(false); setIcon(null); break; case INDETERMINATE: setSelected(false); setIcon(icon); break; default: throw new AssertionError("Unknown Status"); } @Override public void actionPerformed(ActionEvent e) { JCheckBox cb = (JCheckBox) e.getSource(); if (!cb.isSelected()) { cb.setIcon(icon); } else if (cb.getIcon() != null) { cb.setIcon(null); cb.setSelected(false); } } } @Override public void updateUI() { final Icon oi = getIcon(); setIcon(null); removeActionListener(listener); setIcon(null); super.updateUI(); EventQueue.invokeLater(new Runnable() { @Override public void run() { if (listener == null) { listener = new TriStateActionListener(); } Icon icon = new IndeterminateIcon(); listener.setIcon(icon); addActionListener(listener); if (oi != null) { setIcon(icon); } } }); listener = new TriStateActionListener(); icon = new IndeterminateIcon(); listener.setIcon(icon); addActionListener(listener); if (Objects.nonNull(getIcon())) { setIcon(icon); } } }; } class IndeterminateIcon implements Icon { private final Color color = UIManager.getColor("CheckBox.foreground"); // private FOREGROUND = UIManager.getColor("CheckBox.foreground"); private static final Color FOREGROUND = Color.BLACK; private static final int MARGIN = 4; private static final int HEIGHT = 2; private final Icon icon = UIManager.getIcon("CheckBox.icon"); @Override public void paintIcon(Component c, Graphics g, int x, int y) { icon.paintIcon(c, g, x, y); int w = getIconWidth(), h = getIconHeight(); int a = 4, b = 2; Graphics2D g2 = (Graphics2D) g.create(); g2.setPaint(Color.BLACK); g2.translate(x, y); g2.fillRect(a, (h - b) / 2, w - a - a, b); icon.paintIcon(c, g2, 0, 0); g2.setPaint(FOREGROUND); g2.fillRect( MARGIN, (getIconHeight() - HEIGHT) / 2, getIconWidth() - MARGIN - MARGIN, HEIGHT); g2.dispose(); } @Override public int getIconWidth() { return icon.getIconWidth(); } @Override public int getIconHeight() { return icon.getIconHeight(); } } enum Status { SELECTED, DESELECTED, INDETERMINATE } }} * 解説 [#explanation] 上記のサンプルでは、`UIManager.getIcon("CheckBox.icon");`で取得した非選択状態のチェックボックスアイコンの上に横棒を引いて不定状態のアイコンを作成しています。 - `JCheckBox#getIcon()`が`null`の場合、チェックボックスは不定状態であると判定 - 横棒の色は`UIManager.getColor("CheckBox.foreground");`を使用しているが、`LookAndFeel`によっては無意味 - [[JTableHeaderにJCheckBoxを追加してセルの値を切り替える>Swing/TableHeaderCheckBox]]で使用すると、`NimbusLookAndFeel`でアイコンと文字列のベースラインがずれる? - `UIManager.getIcon("CheckBox.icon")`で取得した非選択状態のチェックボックスアイコンの上に一本の横棒を引いて不定状態のアイコンを作成 - `JCheckBox#getIcon()`が`null`の場合、チェックボックスは不定状態であると判定して上記の不定状態のアイコンを表示 - 横棒の色は`UIManager.getColor("CheckBox.foreground")`を使用しているが`LookAndFeel`によっては無意味 - [[JTableHeaderにJCheckBoxを追加してセルの値を切り替える>Swing/TableHeaderCheckBox]]で使用すると`NimbusLookAndFeel`でアイコンと文字列のベースラインがずれる? -- 文字列も`ImageIcon`にして回避 - `NimbusLookAndFeel`で、不定状態アイコンのフォーカスやロールオーバーが表示されない - `NimbusLookAndFeel`で不定状態アイコンのフォーカスやロールオーバーが表示されない * 参考リンク [#reference] - [https://www.javaspecialists.eu/archive/Issue145.html JavaSpecialists 145 - TristateCheckBox Revisited] -- [https://www.javaspecialists.eu/archive/Issue082.html JavaSpecialists 082 - TristateCheckBox based on the Swing JCheckBox] - [https://stackoverflow.com/questions/1263323/tristate-checkboxes-in-java swing - Tristate Checkboxes in Java - Stack Overflow] * コメント [#comment] #comment #comment