Swing/BackgroundButtonIcon のバックアップ(No.5)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/BackgroundButtonIcon へ行く。
- 1 (2015-11-22 (日) 14:13:44)
- 2 (2017-05-24 (水) 17:26:12)
- 3 (2018-05-16 (水) 20:21:47)
- 4 (2020-05-10 (日) 02:33:23)
- 5 (2021-11-02 (火) 02:30:00)
- category: swing folder: BackgroundButtonIcon title: JToggleButtonをFlowLayoutで重ねて表示する tags: [JToggleButton, FlowLayout, Icon, EmptyBorder] author: aterai pubdate: 2015-05-04T00:58:14+09:00 description: ボタンテキストが左揃えの非矩形JToggleButtonをFlowLayoutを使って任意の幅だけ重ねて配置します。 image:
概要
ボタンテキストが左揃えの非矩形JToggleButton
をFlowLayout
を使って任意の幅だけ重ねて配置します。
Screenshot
Advertisement
サンプルコード
private static AbstractButton makeButton(
String title, Color color, final int overlap, boolean first) {
final ToggleButtonBarCellIcon icon = new ToggleButtonBarCellIcon();
AbstractButton b = new JToggleButton(title) {
@Override public boolean contains(int x, int y) {
if (Objects.nonNull(icon) && Objects.nonNull(icon.area)) {
return icon.area.contains(x, y);
} else {
return super.contains(x, y);
}
}
@Override public Dimension getPreferredSize() {
return new Dimension(icon.getIconWidth(), icon.getIconHeight());
}
@Override protected void paintComponent(Graphics g) {
icon.paintIcon(this, g, 0, 0);
super.paintComponent(g);
}
};
b.setIcon(new Icon() {
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(Color.GRAY);
g.drawOval(x, y, 12, 12);
}
@Override public int getIconWidth() {
return 12;
}
@Override public int getIconHeight() {
return 12;
}
});
b.setContentAreaFilled(false);
int th = ToggleButtonBarCellIcon.TH;
if (first) {
b.setBorder(BorderFactory.createEmptyBorder(
0, LINE_WIDTH + BI_GAP, 0, th));
} else {
b.setBorder(BorderFactory.createEmptyBorder(
0, th + LINE_WIDTH + BI_GAP, 0, th));
}
b.setHorizontalAlignment(SwingConstants.LEFT);
b.setFocusPainted(false);
b.setOpaque(false);
b.setBackground(color);
return b;
}
private static JPanel makePanel(int overlap) {
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEADING, -overlap, 0)) {
@Override public boolean isOptimizedDrawingEnabled() {
return false;
}
};
p.setBorder(BorderFactory.createEmptyBorder(0, overlap, 0, 0));
p.setOpaque(false);
return p;
}
private static JComponent makeBreadcrumbList(
int overlap, Color color, List<String> list) {
JPanel p = makePanel(overlap + LINE_WIDTH);
ButtonGroup bg = new ButtonGroup();
boolean f = true;
for (String title : list) {
AbstractButton b = makeButton(title, color, overlap, f);
p.add(b);
bg.add(b);
f = false;
}
return p;
}
View in GitHub: Java, Kotlin解説
FlowLayoutでボタンを重ねてパンくずリストを作成すると同じように、FlowLayout
の配置間隔をマイナスにすることでボタンの重なりを実現していますが、こちらのサンプルではボタンテキストを左揃えにするためにJRadioButton#setIcon(Icon)
とJRadioButton#setHorizontalTextPosition(SwingConstants.CENTER)
は使用せず、以下の3
つのメソッドをオーバーライドしたJToggleButton
を使用しています。
JToggleButton#paintComponent(...)
をオーバーライドして非矩形アイコンを描画JToggleButton#getPreferredSize(...)
をオーバーライドして推奨サイズがアイコンと同じになるように設定JToggleButton#contains(...)
をオーバーライドして非矩形アイコンの外側がマウスに反応しないように設定
- 注:
- アイコンの三角形部分に左揃えした文字列や長い文字列などが被らないようにするため、
JToggleButton
にはEmptyBorder
で開始辺と終了辺に余白を設定している - 最初の
JToggleButton
の開始辺には三角形の高さ分の余白は必要ない
- アイコンの三角形部分に左揃えした文字列や長い文字列などが被らないようにするため、