概要

TitledBorderを背景色を変更する方法をテストします。

スクリーンショット

Swing/TitledBorderBackground.png

サンプルコード

JPanel p1 = new JPanel() {
  @Override protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setPaint(getBackground());
    g2.fill(SwingUtilities.calculateInnerArea(this, null));
    g2.dispose();
    super.paintComponent(g);
  }
};
p1.setBackground(Color.WHITE);
p1.setOpaque(false);
p1.setBorder(BorderFactory.createTitledBorder(title));
View in GitHub: Java, Kotlin

解説

  • Default TitledBorder
    • デフォルトではTitledBorderで使用されるJLabelisOpaque() == trueなのでTitledBorderを設定したJPanelではなくその親JPanelの背景色が表示される
  • Paint TitledBorder background
    • 上記のTransparent TitledBorderとは逆にBorderを描画する領域のみTitledBorderを設定したJPanelの背景を白で塗りつぶすよう設定
      JPanel p2 = new JPanel() {
        @Override protected void paintComponent(Graphics g) {
          Graphics2D g2 = (Graphics2D) g.create();
          g2.setPaint(getBackground());
          Area area = new Area(new Rectangle(getSize()));
          area.subtract(new Area(SwingUtilities.calculateInnerArea(this, null)));
          g2.fill(area);
          g2.dispose();
          super.paintComponent(g);
        }
      };
      
  • Override paintBorder
    • TitledBorder#paintBorder(...)をオーバーライドしてTitledBorderの上辺のみ背景を白で塗りつぶすよう設定
    • TitledBorder#isBorderOpaque(...)はオーバーライドしても効果がない
  • OverlayLayout + JLabel
    • TitledBorderのタイトルは空にして背景色を白に設定したJLabelOverlayLayoutで左上に配置
    • BorderFactory.createTitledBorder("<html><span style='background:white'>html TitledBorder")のようにhtmlタグを使用してタイトルの背景色のみ変更する方法もある
    • Borderの右下にJComponentを配置
    • BorderにJComponentを配置
      JLabel label = new JLabel(title, SwingConstants.LEADING);
      label.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
      label.setOpaque(true);
      label.setBackground(Color.WHITE);
      label.setAlignmentX(Component.LEFT_ALIGNMENT);
      label.setAlignmentY(Component.TOP_ALIGNMENT);
      
      Box box = Box.createHorizontalBox();
      box.add(Box.createHorizontalStrut(8));
      box.add(label);
      box.setAlignmentX(Component.LEFT_ALIGNMENT);
      box.setAlignmentY(Component.TOP_ALIGNMENT);
      
      int height = label.getPreferredSize().height / 2;
      Color color = new Color(0x0, true);
      Border b1 = BorderFactory.createMatteBorder(height, 2, 2, 2, color);
      Border b2 = BorderFactory.createTitledBorder("");
      p.setBorder(BorderFactory.createCompoundBorder(b1, b2));
      p.setAlignmentX(Component.LEFT_ALIGNMENT);
      p.setAlignmentY(Component.TOP_ALIGNMENT);
      
      JPanel panel = new JPanel();
      panel.setLayout(new OverlayLayout(panel));
      panel.add(box);
      panel.add(p);
      

参考リンク

コメント