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 ドキュメントにはコールされる順番は書いてないので、変更されたとしても文句はいえないのですが....
なんだかなぁ...