• category: swing folder: RadioCard title: JToggleButton内に選択状態を同期したJRadioButtonを描画する tags: [JToggleButton, JRadioButton, JLayer] author: aterai pubdate: 2024-11-04T06:54:59+09:00 description: JTobbleButton内に選択状態を同期したJRadioButtonと複数行テキストを配置してRadioCardを作成します。 image: https://drive.google.com/uc?id=1tPWnvgh7N8d-190hKXGddYm9Q71HdwoN

概要

JTobbleButton内に選択状態を同期したJRadioButtonと複数行テキストを配置してRadioCardを作成します。

サンプルコード

private static Component makeRadioIconLayer(AbstractButton button) {
  JRadioButton radio = new JRadioButton();
  radio.setOpaque(false);
  Dimension d = radio.getPreferredSize();
  Insets i = button.getInsets();
  button.setMargin(new Insets(i.top, d.width, i.bottom, i.right));
  button.setPreferredSize(button.getPreferredSize());
  button.setVerticalAlignment(SwingConstants.TOP);
  LayerUI<AbstractButton> layer = new LayerUI<AbstractButton>() {
    @Override public void paint(Graphics g, JComponent c) {
      super.paint(g, c);
      if (c instanceof JLayer) {
        AbstractButton b = (AbstractButton) ((JLayer<?>) c).getView();
        Graphics2D g2 = (Graphics2D) g.create();
        radio.setSelected(b.isSelected());
        int x = i.left - d.width + 8;
        int y = i.top + 8;
        SwingUtilities.paintComponent(
            g2, radio, b, x, y, d.width, d.height);
        g2.dispose();
      }
    }
  };
  return new JLayer<>(button, layer);
}
View in GitHub: Java, Kotlin

解説

  • JTobbleButton<html>タグで複数行のテキストを設定してカードを作成
  • JTobbleButtonJLayerを設定してその左余白にJRadioButtonを描画
    • JTobbleButtonJLayerを適用するとその高さが一行分?まで縮小してしまう?
    • JLayerを適用する前の推奨サイズをJTobbleButton#setPreferredSize(...)で設定してこれを回避
    • この回避方法はLookAndFeelの変更には対応していない
  • LayerUI#paint(...)をオーバーライドしてSwingUtilities.paintComponent(...)JRadioButtonを描画しているのでJRadioButtonのクリックは親のJTobbleButtonのクリックになる
    • LayerUI#paint(...)内でradio.setSelected(toggle.isSelected())を実行してJRadioButtonJTobbleButtonの選択状態が同期するよう設定

参考リンク

コメント