SwingComponent の挙動が変わった?
もう 1 つのメニューの問題も原因が分かりました。こちらはバグではないと思いますが、ちょっと微妙。
JPopupMenu を表示させるためには、親のコンポーネントを引数にしてshow メソッドをコールします。
ここで、親のコンポーネントが取れないといっていたのが、前回の問題。それはあっけなく解決しました。
以前は次のように書いてました。
var panel = (node.impl_createPGNode() as SGGroup).getPanel();
Node クラスの impl_createPGNode 関数が間違っていたようです。
ただしくは impl_getPGNode 関数でした。
var panel = (node.impl_getPGNode() as SGGroup).getPanel();
ただし、impl_getPGNode 関数のように impl_ からはじまる関数はあくまでも内部的に使う関数なので、バージョンアップで変更されても文句はいえません ^ ^;;
なので、これはかまわないのです。
スクリプトをこのように変更することで、メニューは表示されます。しかし、問題は項目が表示されないことなのです。
表示されるのはちっちゃい四角だけ。なんだこりゃ?
以前はポップアップのクラスは次のように書いていました。
public class PopupMenu extends SwingComponent { public var label: String; public-init var items: Menu[]; var popupMenu: JPopupMenu; override function createJComponent(): JComponent { popupMenu = new JPopupMenu(); // ラベルの設定 popupMenu.setLabel(label); // 項目の追加 for (item in items) { popupMenu.add(item.getJComponent()); } return popupMenu; } public function show(node: Node, x: Integer, y: Integer): Void { var panel = (node.impl_getPGNode() as SGGroup).getPanel(); popupMenu.show(panel, x, y); } }
つまり、メニューに項目を追加するのは createJComponent 関数で行なっていたわけです。
JavaFX 1.1 までは createJComponent 関数がコールされるのは、インスタンス変数がセットされた後でした。つまり、上のスクリプトでは items がセットされていたのです。
ところが、JavaFX 1.2 では items がセットされない状態で createJComponent 関数がコールされてしまいます。
このため、項目がないメニューが表示されてしまったのです。
時系列で表すと
- createJComponent をコール
- インスタンス変数をセット
- init を実行
- postinit を実行
となっているようです。
ここまで分かれば、修正するのは簡単。以下のように変更しました。
public class PopupMenu extends SwingComponent { public var label: String; public-init var items: Menu[]; var popupMenu: JPopupMenu; init { // ラベルの設定 popupMenu.setLabel(label); // 項目の追加 for (item in items) { popupMenu.add(item.getJComponent()); } } override function createJComponent(): JComponent { popupMenu = new JPopupMenu(); return popupMenu; } public function show(node: Node, x: Integer, y: Integer): Void { var panel = (node.impl_getPGNode() as SGGroup).getPanel(); popupMenu.show(panel, x, y); } }
同じように JMenu クラスに対応する Menu クラスと、JMenuItem クラスに MenuItem クラスも変更しました。
その結果、ちゃんとメニューが表示されるようになったのです。
もともと、API ドキュメントにはコールされる順番は書いてないので、変更されたとしても文句はいえないのですが....
なんだかなぁ...