-
Notifications
You must be signed in to change notification settings - Fork 461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8242489: ChoiceBox: initially toggle not sync'ed to selection #177
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/* | ||
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. | ||
* Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
|
@@ -28,9 +28,6 @@ | |
import com.sun.javafx.scene.control.ContextMenuContent; | ||
import com.sun.javafx.scene.control.behavior.BehaviorBase; | ||
import javafx.beans.WeakInvalidationListener; | ||
import javafx.scene.Node; | ||
import javafx.scene.control.Accordion; | ||
import javafx.scene.control.Button; | ||
import javafx.scene.control.Control; | ||
import javafx.scene.control.SkinBase; | ||
import javafx.util.StringConverter; | ||
|
@@ -156,20 +153,11 @@ public ChoiceBoxSkin(ChoiceBox<T> control) { | |
registerChangeListener(control.selectionModelProperty(), e -> updateSelectionModel()); | ||
registerChangeListener(control.showingProperty(), e -> { | ||
if (getSkinnable().isShowing()) { | ||
MenuItem item = null; | ||
|
||
SelectionModel sm = getSkinnable().getSelectionModel(); | ||
SelectionModel<T> sm = getSkinnable().getSelectionModel(); | ||
if (sm == null) return; | ||
|
||
long currentSelectedIndex = sm.getSelectedIndex(); | ||
int itemInControlCount = choiceBoxItems.size(); | ||
boolean hasSelection = currentSelectedIndex >= 0 && currentSelectedIndex < itemInControlCount; | ||
if (hasSelection) { | ||
item = popup.getItems().get((int) currentSelectedIndex); | ||
if (item != null && item instanceof RadioMenuItem) ((RadioMenuItem)item).setSelected(true); | ||
} else { | ||
if (itemInControlCount > 0) item = popup.getItems().get(0); | ||
} | ||
|
||
// This is a fix for RT-9071. Ideally this won't be necessary in | ||
// the long-run, but for now at least this resolves the | ||
|
@@ -201,15 +189,6 @@ public ChoiceBoxSkin(ChoiceBox<T> control) { | |
label.setText(""); // clear label text when selectedIndex is -1 | ||
} | ||
}); | ||
registerChangeListener(control.getSelectionModel().selectedItemProperty(), e -> { | ||
if (getSkinnable().getSelectionModel() != null) { | ||
int index = getSkinnable().getSelectionModel().getSelectedIndex(); | ||
if (index != -1) { | ||
MenuItem item = popup.getItems().get(index); | ||
if (item instanceof RadioMenuItem) ((RadioMenuItem)item).setSelected(true); | ||
} | ||
} | ||
}); | ||
registerChangeListener(control.converterProperty(), e -> { | ||
updateChoiceBoxItems(); | ||
updatePopupItems(); | ||
|
@@ -364,6 +343,11 @@ String getChoiceBoxSelectedText() { | |
return label.getText(); | ||
} | ||
|
||
// Test only purpose | ||
ContextMenu getChoiceBoxPopup() { | ||
return popup; | ||
} | ||
|
||
private void addPopupItem(final T o, int i) { | ||
MenuItem popupItem = null; | ||
if (o instanceof Separator) { | ||
|
@@ -428,6 +412,9 @@ private void updateSelection() { | |
MenuItem selectedItem = popup.getItems().get(selectedIndex); | ||
if (selectedItem instanceof RadioMenuItem) { | ||
((RadioMenuItem) selectedItem).setSelected(true); | ||
} else { | ||
// need to unselect toggles if selectionModel allows a Separator/MenuItem | ||
// to be selected | ||
toggleGroup.selectToggle(null); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The The fix in this PR looks good to me. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, you are right: a) the implementation of ChoiceBoxSelectionModel is broken when it comes to handling of unselectable items (such as Separator): next/previous try to move on, the others simply select. The implementation changed in fix of JDK-8088261 - before select(index) tried to handle it, after this was moved into next/previous. Arguably, the model can do what it wants without specification ;) b) the skin is responsible to sync the selection state of its toggles with the state of model: if the selectedIndex/Item does not have a corresponding toggle (f.i. if it's a separator), all toggles must be unselected. c) my test related to the Separator is broken - as you correctly noted, it will fail if a future implementation decides to select a really selectable item :) My plan:
Thanks for the extensive review, very much appreciated :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw: just noticed that there are methods in ChoiceBoxSkin testing the fix for next/prev
the name look like they want to point to the corresponding issue .. but the id is incorrect: that id doesn't exist, should be 8088261 (spelling error, I think) - is it okay to change them to the right id? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I am good with this. Though I will file a JBS for the correction in ChoiceBoxSelectionModel.
Thanks for link to JDK-8088261, As mentioned in this bug description, "Culprit is an incorrect override of select(int): it may reject the new index if that would select a separator, but it must not select an arbitrary index instead", So It is not sure to me what should There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That will be good to change, but not sure if as part of this bug. It will be unrelated to fix. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the end and following your latest comments I did nothing Except adding code comments to the separator test and the else (toggle nulling) branch. |
||
} | ||
// update the label | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would recommend to prefix the method name with
test_.
It is not followed across, onlyTabPaneSkin
hastest_
prefixed method.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, as TabPaneSkin is a singularity in controls (in graphics such a pattern seems to be wider-spread), I would prefer not to do it here - also because ChoiceBoxSkin has another test-only accessor (for label text) which doesn't. Might be a candidate for a general cleanup task - if we decide to really introduce such a naming convention (which I personally wouldn't like :)