JDK8u40 で追加された Spinner と Dialog を試してみた。 とりあえず回避方法をみつけた。
JDK8u40 で追加された Spinner と Dialog を試してみた。
このエントリーで Arrow button をマウスクリックして操作した場合、呼び出す Dialog を Modality.APPLICATION_MODAL または Modality.WINDOW_MODAL に設定すると
Spinner のインクリメントもしくはデクリメントが止まらないという不思議な現象に悩まされました。
キーボードのカーソルキーでの操作では期待通りに正常に動きます。
なんでマウスで Arrow button をクリックして操作するといけないのか?
MousePressed がブロックされずに押しっぱなし状態で SpinnerBehavior クラスの startSpinning(boolean increment) の Timeline が動いちゃってるようです。
そこで、愚かなアイディアですが MouseReleased が発生してから Dialog を呼び出しちゃえってやってみたら期待通りに動いてくれました。
ごめんなさい。こんな方法しか思いつきませんでした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
spinner.valueProperty().addListener((ov, oldValue, newValue) -> { System.out.println(newValue); spinner.setOnMouseReleased(e -> { if (newValue <= 30_000 && poor.getValue()) { poor.setValue(Boolean.FALSE); showPoorDialog(); } if (newValue >= 70_000 && rich.getValue()) { rich.setValue(Boolean.FALSE); showRichDialog(); } }); spinner.setOnKeyReleased(e -> { if (newValue <= 30_000 && poor.getValue()) { poor.setValue(Boolean.FALSE); showPoorDialog(); } if (newValue >= 70_000 && rich.getValue()) { rich.setValue(Boolean.FALSE); showRichDialog(); } }); }); |
と言うことでお終いです。
これってやっぱりバグなんだろうか?
追記:Jose Pereda さんよりコメントをいただきました。
それによると SpinnerSkin class に問題があるようです。
詳しくは Jose さんのコメントをご覧ください。
あわせてこの問題に対する素晴らしい解決方法を提示してくれましたのでエントリー本文にも記載させていただきます。
素晴らしいコードをありがとうございました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
private SpinnerBehavior<Integer> beh; @Override public void initialize(URL url, ResourceBundle rb) { spinner.valueProperty().addListener((ov, oldValue, newValue) -> { System.out.println(newValue); if (beh == null) { beh = (SpinnerBehavior) ((SpinnerSkin) (spinner.getSkin())).getBehavior(); spinner.focusedProperty().addListener((obs, b, b1) -> { if (b && !b1) { beh.stopSpinning(); } }); } if (newValue <= 30_000 && poor.getValue()) { poor.setValue(Boolean.FALSE); showPoorDialog(); } if (newValue >= 70_000 && rich.getValue()) { rich.setValue(Boolean.FALSE); showRichDialog(); } }); } |
TAGS: JavaFX | 2015年3月13日12:02 AM
Comment-
Jose Peredasays:
-
ゆっちsays:
ゆっちのBlog » JDK8u40 で追加された Formatted Text も試してみた。
2015年3月13日 2:54 AM
The problem is in the SpinnerSkin class:
incrementArrowButton.setOnMousePressed(e -> {
getSkinnable().requestFocus();
getBehavior().startSpinning(true);
});
This assumes the spinner keeps the focus all the time, which in the case of a modal dialog is not true.
The proper solution should be added to the API, so an issue should be opened at Jira with this bug.
Your solution works, but only if you are using the mouse. So with a keyboard you wouldn’t show the dialogs…
This is my approach. You can get a (private API) SpinnerBehavior instance and check it for yourself:
private SpinnerBehavior beh;
@Override
public void initialize(URL url, ResourceBundle rb) {
spinner.valueProperty().addListener((ov, oldValue, newValue) -> {
if(beh==null){
beh = (SpinnerBehavior)((SpinnerSkin)(spinner.getSkin())).getBehavior();
spinner.focusedProperty().addListener((obs,b,b1)->{
if(b && !b1){
beh.stopSpinning();
}
});
}
…
});
}
Also I find annoying that if you spin with your mouse, it’s very very slow, while with the keyboard is really fast… There’s a timeline with 750ms delay for mouse, but no delay for keyboard.
Best regards,
Jose
2015年3月13日 7:26 AM
wonderful!
Your presentation code is best to resolve this problem.
Thanks! 🙂
Trackback
2015年3月26日8:58 PM(編集)
[...] JDK8u40 で追加された Spinner と Dialog を試してみた。 とりあえず回避方法をみつけた。 [...]
Trackback URL