概要

JToolTipGlassPane上のコンポーネントに追加した場合でも、手前に表示されるように設定します。主にSwing - ComboBox scroll and selected/highlight on glasspaneを参考にしています。

サンプルコード

//Swing - ComboBox scroll and selected/highlight on glasspane
//https://community.oracle.com/thread/1357949
try {
  Class clazz = Class.forName("javax.swing.PopupFactory");
  Field field = clazz.getDeclaredField("forceHeavyWeightPopupKey");
  field.setAccessible(true);
  label2.putClientProperty(field.get(null), Boolean.TRUE);
} catch (Exception ex) {
  ex.printStackTrace();
}
view all

解説

上記のサンプルでは、ボタンをクリックすると、二つのラベルをもつGlassPaneが表示されます。

  • 111...(左)
    • GlassPaneの下にJToolTipが表示される
    • 親フレームの外にJToolTipがはみ出す場合は、正常に表示される
    • ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);では効果なし?
  • 222...(右)
    • 正常に表示されるように、常に、JToolTipを重量コンポーネントとして表示している
    • PopupFactoryクラスのforceHeavyWeightPopupKeyをリフレクションで取得して、JComponent#putClientPropertyメソッドで設定
    • Swing - ComboBox scroll and selected/highlight on glasspaneGlassPaneJComboBoxのポップアップを正常に表示する方法を引用
    • ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);としておかないと前面に表示されない環境がある?

JDK 1.7.0の場合は、javax.swing.PopupFactory.forceHeavyWeightPopupKeyが無くなってしまったので、以下のように javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUPを使用します。

Class clazz = Class.forName("javax.swing.ClientPropertyKey");
Field field = clazz.getDeclaredField("PopupFactory_FORCE_HEAVYWEIGHT_POPUP");
field.setAccessible(true);
combo.putClientProperty(field.get(null), Boolean.TRUE);

参考リンク

コメント

*** src7u5/javax/swing/PopupFactory.java	Wed May 16 07:54:10 2012
--- src7u6/javax/swing/PopupFactory.java	Fri Aug 10 10:01:16 2012
************** *
*** 203,214 ****
                      popupType = HEAVY_WEIGHT_POPUP;
                      break;
                  }
- } else if (c instanceof Window) {
- Window w = (Window) c;
- if (!w.isOpaque() || w.getOpacity() < 1 || w.getShape() != null) {
- popupType = HEAVY_WEIGHT_POPUP;
- break;
- }
              }
              c = c.getParent();
          }
--- 203,208 ----