Для MQTT.fx я хотел использовать ToggleButtons, например, чтобы выбрать декодирование сообщения MQTT или уровень QoS:
Я обнаружил, что в контексте ToggleGroup ToggleButtons ведут себя не так, как RadioButtons, с точки зрения выбора / отмены выбора: в отличие от RadioButtons ToggleButtons все еще можно установить в невыбранное состояние.
RadioButton расширяет ToggleButton и переопределяет fire () (который вызывается, когда пользовательский жест указывает на то, что событие для этой ButtonBase
должно произойти, иначе «кнопка была нажата»):
Переключатель:
1
2
3
4
5
6
|
@Override public void fire() { // we don't toggle from selected to not selected if part of a group if (getToggleGroup() == null || !isSelected()) { super .fire(); } } |
Кнопка-переключатель:
1
2
3
4
|
@Override public void fire() { setSelected(!isSelected()); fireEvent( new ActionEvent()); } |
В ToogleGroup кнопки ToggleButtons должны вести себя как RadioButtons, поэтому, ИМХО, это ошибка, заслуживающая запроса извлечения для ToggleButton & # 5587; & # 56841;
Один из способов справиться с этим — создать собственное расширение ToggleButton, реализующее fire () по отношению к RadioButton.
Но мне больше нравится добавлять поведение в существующие элементы управления.
Это мой трюк для изменения поведения по умолчанию, добавив фильтры ко всем кнопкам ToogleButtonGroup, использующим нежелательные события MouseEvents:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public class JavaFXUtil { private static JavaFXUtil me; private JavaFXUtil() { } public static JavaFXUtil get() { if (me == null ) { me = new JavaFXUtil(); } return me; } public EventHandler<MouseEvent> consumeMouseEventfilter = (MouseEvent mouseEvent) -> { if (((Toggle) mouseEvent.getSource()).isSelected()) { mouseEvent.consume(); } }; public void addAlwaysOneSelectedSupport( final ToggleGroup toggleGroup) { toggleGroup.getToggles().addListener((Change<? extends Toggle> c) -> { while (c.next()) { for ( final Toggle addedToggle : c.getAddedSubList()) { addConsumeMouseEventfilter(addedToggle); } } }); toggleGroup.getToggles().forEach(t -> { addConsumeMouseEventfilter(t); }); } private void addConsumeMouseEventfilter(Toggle toggle) { ((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_PRESSED, consumeMouseEventfilter); ((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_RELEASED, consumeMouseEventfilter); ((ToggleButton) toggle).addEventFilter(MouseEvent.MOUSE_CLICKED, consumeMouseEventfilter); } } |
01
02
03
04
05
06
07
08
09
10
11
12
13
|
public class ButtonDemoController { @FXML private ToggleGroup g2; @FXML private ToggleGroup g3; public void initialize() { JavaFXUtil.get().addAlwaysOneSelectedSupport(g2); JavaFXUtil.get().addAlwaysOneSelectedSupport(g3); } } |
Пример кода на GitHub .
Ссылка: | Кнопка выбора: используйте ToggleButtons как RadioButtons от нашего партнера JCG Дженса Детерса в блоге JavaFX Delight . |