Summary

JPopupMenuのラベルをTitledBorderを使用してタイトル表示するよう設定します。

Source Code Examples

JPopupMenu popup1 = new JPopupMenu("JPopupMenu#setLabel(...)") {
  @Override public void updateUI() {
    setBorder(null);
    super.updateUI();
    Border border = getBorder();
    String title = getLabel();
    if (!isCompoundMotifBorderBorder(border) && title != null) {
      Color color = UIManager.getColor("Separator.foreground");
      Border underline = BorderFactory.createMatteBorder(1, 0, 0, 0, color);
      Border labelBorder = BorderFactory.createTitledBorder(
          underline,
          title,
          TitledBorder.CENTER,
          TitledBorder.ABOVE_TOP,
          getFont(),
          getForeground());
      setBorder(BorderFactory.createCompoundBorder(border, labelBorder));
    }
  }
};

private static boolean isCompoundMotifBorderBorder(Border border) {
  boolean b0 = border instanceof CompoundBorder;
  boolean b1 = b0 && isMotifBorder(((CompoundBorder) border).getInsideBorder());
  boolean b2 = b0 && isMotifBorder(((CompoundBorder) border).getOutsideBorder());
  return b1 || b2;
}

private static boolean isMotifBorder(Border border) {
  return border.getClass().getName().contains("MotifBorders");
}
View in GitHub: Java, Kotlin

Description

  • 左:
    • MotifLookAndFeelではデフォルトでJPopupMenu#setLabel(title)で設定したタイトルがMotifBorders$MotifPopupMenuBorderを使用してBorderとして表示される
    • MotifLookAndFeel以外ではJPopupMenu#setLabel(title)でタイトルを設定しても表示には使用されない
  • 右:
    • MotifLookAndFeel以外でもJPopupMenu#setLabel(title)で設定されたタイトルを表示するようTitledBorderMatteBorderJPopupMenuLookAndFeelデフォルトBorderCompoundBorderで組み合わせてタイトル表示するBorderを作成
    • MotifLookAndFeelの場合はタイトル表示が重複しないよう上記のBorderは設定しないが、LookAndFeelJPopupMenuに設定したタイトルを表示するかどうかをチェックする方法が存在しない?
      • このため、このサンプルではCompoundBorderInsideBorderOutsideBorderのどちらかのクラス名にMotifBordersが含まれているかどうかで判断している

Reference

Comment