概要
JCheckBox
の選択状態、非選択状態に加えて不定状態を表すアイコンを追加します。
Screenshot

Advertisement
サンプルコード
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;
}
@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();
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);
}
}
});
}
};
class IndeterminateIcon implements Icon {
private final Color color = UIManager.getColor("CheckBox.foreground");
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);
g2.dispose();
}
@Override public int getIconWidth() {
return icon.getIconWidth();
}
@Override public int getIconHeight() {
return icon.getIconHeight();
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、UIManager.getIcon("CheckBox.icon")
で取得した非選択状態のチェックボックスアイコンの上に横棒を引いて不定状態のアイコンを作成しています。
JCheckBox#getIcon()
がnull
の場合、チェックボックスは不定状態であると判定- 横棒の色は
UIManager.getColor("CheckBox.foreground")
を使用しているがLookAndFeel
によっては無意味 - JTableHeaderにJCheckBoxを追加してセルの値を切り替えるで使用すると
NimbusLookAndFeel
でアイコンと文字列のベースラインがずれる?- 文字列も
ImageIcon
にして回避
- 文字列も
NimbusLookAndFeel
で不定状態アイコンのフォーカスやロールオーバーが表示されない