JavaFX Toggle MenuButton

Есть ли JavaFX MenuButton (в частности, SplitMenuButton), который также позволяет переключать его выбранное состояние? Эквивалентом Swing будет OpenIDE JToggleButton, который вы можете создать как:

JToggleButton button = DropDownButtonFactory.createDropDownToggleButton(icon, menu)

Итак, когда пользователь щелкает по области действия, выбранное состояние кнопки должно переключаться в дополнение к срабатыванию того, что связано со свойством ButtonBase.onAction. При нажатии стрелки должно появиться раскрывающееся меню, как и ожидалось.

Я пока не видел реализации этого. Как проще всего реализовать эту функцию самостоятельно? Я думал просто расширить SplitMenuButton, добавив дополнительное поле для отслеживания выбранного состояния, а затем по-разному отрисовывать фон в зависимости от этого состояния.

wcmatthysen 13.04.2018 10:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
444
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, думаю, мне удалось это понять. Вам нужно создать новый класс с именем ToggleSplitMenuButton, который расширяется от SplitMenuButton:

import java.net.URL;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.BooleanPropertyBase;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.event.ActionEvent;
import javafx.scene.AccessibleAttribute;
import javafx.scene.control.MenuItem;
import javafx.scene.control.SplitMenuButton;

public class ToggleSplitMenuButton extends SplitMenuButton {

    private static final String STYLESHEET = "toggle-split-menu-button.css";

    /***************************************************************************
     *                                                                         *
     * Constructors                                                            *
     *                                                                         *
     **************************************************************************/

    public ToggleSplitMenuButton() {
        super();
        initialize();
    }

    public ToggleSplitMenuButton(MenuItem ... items) {
        super(items);
        initialize();
    }

    private void initialize() {
        Class<?> clazz = getClass();
        URL resource = clazz.getResource(STYLESHEET);
        String stylesheet = resource.toExternalForm();
        ObservableList<String> stylesheets = getStylesheets();
        stylesheets.add(stylesheet);
    }

    /***************************************************************************
     *                                                                         *
     * Properties                                                              *
     *                                                                         *
     **************************************************************************/
    /**
     * Indicates whether this toggle split menu button is selected. This can be
     * manipulated programmatically.
     */
    private BooleanProperty selected;

    public final void setSelected(boolean value) {
        selectedProperty().set(value);
    }

    public final boolean isSelected() {
        return selected == null ? false : selected.get();
    }

    public final BooleanProperty selectedProperty() {
        if (selected == null) {
            selected = new BooleanPropertyBase() {

                @Override
                protected void invalidated() {
                    final boolean selected = get();
                    pseudoClassStateChanged(PSEUDO_CLASS_SELECTED, selected);
                    notifyAccessibleAttributeChanged(AccessibleAttribute.SELECTED);
                }

                @Override
                public Object getBean() {
                    return ToggleSplitMenuButton.this;
                }

                @Override
                public String getName() {
                    return "selected";
                }
            };
        }
        return selected;
    }

    /***************************************************************************
     *                                                                         *
     * Methods                                                                 *
     *                                                                         *
     **************************************************************************/

    @Override
    public void fire() {
        if (!isDisabled()) {
            setSelected(!isSelected());
            fireEvent(new ActionEvent());
        }
    }

    /***************************************************************************
     *                                                                         *
     * Stylesheet Handling                                                     *
     *                                                                         *
     **************************************************************************/

    private static final PseudoClass PSEUDO_CLASS_SELECTED = PseudoClass.getPseudoClass("selected");
}

Вам также необходимо создать соответствующую таблицу стилей (называемую переключение-разделение-меню-кнопка.css), чтобы правильно стилизовать компонент:

.split-menu-button:selected > .label {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom, derive(-fx-outer-border, -20%), -fx-outer-border),
        linear-gradient(to bottom,
                derive(-fx-color, -22%) 0%,
                derive(-fx-color, -13%) 20%,
                derive(-fx-color, -11%) 50%);
}
.split-menu-button:selected > .arrow-button {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom, derive(-fx-outer-border, -20%), -fx-outer-border),
        linear-gradient(to bottom,
                derive(-fx-color, -22%) 0%,
                derive(-fx-color, -13%) 20%,
                derive(-fx-color, -11%) 50%);
}
.split-menu-button:selected:focused > .label {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom,
            derive(-fx-color, -22%) 0%,
            derive(-fx-color, -13%) 20%,
            derive(-fx-color, -11%) 50%),
        -fx-faint-focus-color,
        linear-gradient(to bottom,
            derive(-fx-color, -22%) 0%,
            derive(-fx-color, -13%) 20%,
            derive(-fx-color, -11%) 50%);
}
.split-menu-button:selected:focused > .arrow-button {
    -fx-background-color:
        -fx-shadow-highlight-color,
        linear-gradient(to bottom,
            derive(-fx-color, -22%) 0%,
            derive(-fx-color, -13%) 20%,
            derive(-fx-color, -11%) 50%),
        -fx-faint-focus-color,
        linear-gradient(to bottom,
            derive(-fx-color, -22%) 0%,
            derive(-fx-color, -13%) 20%,
            derive(-fx-color, -11%) 50%);
}

Другие вопросы по теме