概要

JOptionPaneで使用されている子JPanelをすべて透明化して背景色を指定した色に変更します。

スクリーンショット

Swing/OptionPaneBackground.png

サンプルコード

UIManager.put("OptionPane.background", Color.LIGHT_GRAY);
String txt = "<html>JOptionPane:<br><li>messageArea<li>realBody<li>separator<li>body<li>buttonArea";
String title = "Title";
int type = JOptionPane.WARNING_MESSAGE;

JLabel label = new JLabel(txt);
label.addHierarchyListener(e -> {
  Component c = e.getComponent();
  if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && c.isShowing()) {
    stream(SwingUtilities.getAncestorOfClass(JOptionPane.class, c))
        .filter(JPanel.class::isInstance)
        .map(JPanel.class::cast) // TEST: .peek(cc -> System.out.println(cc.getName()))
        .forEach(p -> p.setOpaque(false));
  }
});

JButton b2 = new JButton("background");
b2.addActionListener(e -> JOptionPane.showMessageDialog(b2.getRootPane(), label, title, type));
view all

解説

  • default
    • UIManager.put("OptionPane.background", Color.LIGHT_GRAY)JOptionPaneの背景色を変更
    • JOptionPaneで使用されている子JPanelが不透明のため、フチの色のみ変更される
  • background
    • UIManager.put("OptionPane.background", Color.LIGHT_GRAY)JOptionPaneの背景色を変更
    • メッセージ用コンポーネントにHierarchyListenerを追加してJOptionPaneのオープンイベントを取得
    • JOptionPaneが表示状態になったらその子JPanelを検索し、すべてsetOpaque(false)で透明化
    • デフォルトのJOptionPaneは以下の名前の5つのJPanelで構成されている
      • OptionPane.messageArea
      • OptionPane.realBody
      • OptionPane.separator
      • OptionPane.body
      • OptionPane.buttonArea
  • override
    • JOptionPane.paintComponent(...)をオーバーライドして背景を任意のTextureに変更
    • JOptionPaneの子JPanelを検索し、すべてsetOpaque(false)で透明化

参考リンク

コメント