Swing/ForceHeavyWeightPopupKey の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ForceHeavyWeightPopupKey へ行く。
- Swing/ForceHeavyWeightPopupKey の差分を削除
--- category: swing folder: ForceHeavyWeightPopupKey title: JToolTipをGlassPane上のコンポーネントで表示する tags: [JToolTip, GlassPane, ToolTipManager, PopupFactory] author: aterai pubdate: 2009-05-11T16:10:58+09:00 description: JToolTipをGlassPane上のコンポーネントに追加した場合でも、手前に表示されるように設定します。 image: https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTNMeZI4ZI/AAAAAAAAAaY/8XHy9j6jQw0/s800/ForceHeavyWeightPopupKey.png --- * Summary [#summary] `JToolTip`を`GlassPane`上のコンポーネントに追加した場合でも、手前に表示されるように設定します。主に[https://community.oracle.com/thread/1357949 Swing - ComboBox scroll and selected/highlight on glasspane]を参考にしています。 #download(https://lh6.googleusercontent.com/_9Z4BYR88imo/TQTNMeZI4ZI/AAAAAAAAAaY/8XHy9j6jQw0/s800/ForceHeavyWeightPopupKey.png) * Source Code Examples [#sourcecode] #code(link){{ // 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(); } }} * Explanation [#explanation] 上記のサンプルでは、ボタンをクリックすると、二つのラベルをもつ`GlassPane`が表示されます。 - `111...`(左) -- `GlassPane`の下に`JToolTip`が表示される -- 親フレームの外に`JToolTip`がはみ出す場合は、正常に表示される -- %%`ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);`では効果なし?%% - `222...`(右) -- 正常に表示されるように常に`JToolTip`を重量コンポーネントとして表示している -- `PopupFactory`クラスの`forceHeavyWeightPopupKey`をリフレクションで取得して`JComponent#putClientProperty`メソッドで設定 -- [https://community.oracle.com/thread/1357949 Swing - ComboBox scroll and selected/highlight on glasspane]の`GlassPane`で`JComboBox`のポップアップを正常に表示する方法を引用 -- `ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);`を設定しないと前面に表示されない環境がある? ---- - `JDK 1.7.0`から`javax.swing.PopupFactory.forceHeavyWeightPopupKey`が無くなってしまったので、以下のように `javax.swing.ClientPropertyKey.PopupFactory_FORCE_HEAVYWEIGHT_POPUP`を使用する必要がある #code{{ 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); }} ---- - `Java 9`以降では以下のようなコードで`Popup`を常に`HeavyWeight`で開くことが可能になった -- [https://bugs.openjdk.org/browse/JDK-8147521 JDK-8147521 macosx Internal API Usage: setPopupType used to force creation of heavyweight popup - Java Bug System] #code{{ PopupFactory.setSharedInstance(new PopupFactory() { @Override public Popup getPopup(Component owner, Component contents, int x, int y) throws IllegalArgumentException { // @param isHeavyWeightPopup true if Popup should be heavy weight, // protected Popup getPopup(..., boolean isHeavyWeightPopup) ... return super.getPopup(owner, contents, x, y, true); } }); }} * Reference [#reference] - [https://community.oracle.com/thread/1357949 Swing - ComboBox scroll and selected/highlight on glasspane] - [http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?mode=viewtopic&topic=42615&forum=12 JComboBox の GlassPane 上でのレンダリング] - [https://community.oracle.com/thread/1366094 Swing - Why glass pane requires setLightWeightPopupEnabled(false)?] - [https://ateraimemo.com/Swing/ModalInternalFrame.html JInternalFrameをModalにする] - [http://www.oracle.com/technetwork/articles/java/mixing-components-433992.html Mixing Heavyweight and Lightweight Components] - [[JPopupMenuを常に重量ポップアップで開く>Swing/LightWeightPopupEnabled]] * コメント [#comment] * Comment [#comment] #comment - `ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);`がバージョンによって効かない場合があるらしい。[https://stackoverflow.com/questions/17150483/force-heavyweight-tooltip-with-shaped-jpanel java - Force HeavyWeight Tooltip with shaped JPanel - Stack Overflow] -- &user(aterai); &new{2013-06-18 (火) 08:34:11}; -- 上記のリンクのサンプルコードだと、`Windows 7` + `JDK 1.7.0_05`: `OK`, `JDK 1.7.0_06`: `NG`。 -- &user(aterai); &new{2013-06-18 (火) 08:42:24}; -- [https://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/4acd0211f48b jdk8/jdk8/jdk: changeset 5453:4acd0211f48b] #code{{ *** 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 ---- }} - [https://bugs.openjdk.org/browse/JDK-2224554 Bug ID: 2224554 Version 7 doesn't support translucent popup menus against a translucent window]の修正が関係しているようだ。半透明の`Window`を使わないで、変わった形の`Window`を使う場合は、丁度この記事などのようにリフレクションを使って常に`PopupFactory_FORCE_HEAVYWEIGHT_POPUP`にした方が良さそう。 -- &user(aterai); &new{2013-06-18 (火) 14:11:40}; -- 去年`Swing Dev ML`で議論されている。[https://mail.openjdk.org/pipermail/swing-dev/2012-June/002096.html <Swing Dev> (8) Review request for 7156657 Version 7 doesn't support translucent popup menus against a translucent window] -- &user(aterai); &new{2013-06-18 (火) 14:19:21}; #comment