如何强制我的自定义皮肤被我的JavaFX应用程序中的所有按钮使用?

时间:2018-04-09 10:17:10

标签: java javafx fxml fxmlloader

假设我为Button写了一个新皮肤 在JavaFX 8中,它看起来像:

import com.sun.javafx.scene.control.skin.ButtonSkin;

// This is quite dirty because of using non-stable api:
public class MyButtonSkin extends ButtonSkin {
    ...
}

然后我希望在我的应用程序中为FXMLLoader创建的每个按钮使用此外观(通过<Button ...> fxml-element) 我不想更改fxml文件。

我的问题是:

在JavaFX 8中有什么可能做到这一点?

可以使用一些DI框架吗?

那么JavaFX 9呢?

附加代码示例:

这个皮肤为按钮引入了新的underkeypress伪类:

import com.sun.javafx.scene.control.skin.ButtonSkin;
import javafx.css.PseudoClass;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

public class MyButtonSkin extends ButtonSkin {
    private static final PseudoClass PSEUDO_CLASS_UNDERKEYPRESS = PseudoClass.getPseudoClass("underkeypress");

    public MyButtonSkin(Button button) {
        super(button);
        button.addEventFilter(KeyEvent.KEY_PRESSED,
                (event -> {
                    if (event.getCode() == KeyCode.SPACE) {
                        pseudoClassStateChanged(PSEUDO_CLASS_UNDERKEYPRESS, true);
                    }
                }));
        button.addEventFilter(KeyEvent.KEY_RELEASED,
                (event -> {
                    if (event.getCode() == KeyCode.SPACE) {
                        pseudoClassStateChanged(PSEUDO_CLASS_UNDERKEYPRESS, false);
                    }
                }));
    }
}

该伪类应该通过CSS使用,如:

.button:underkeypress {
    -fx-base: red;
}

1 个答案:

答案 0 :(得分:2)

正如@kleopatra所说,将场景应用于场景中所有Button的最佳方法是使用CSS样式表。

.button {
    -fx-skin: "my.package.MyButtonSkin";
}

将此样式表应用于场景的根

Parent root = loader.load(); // load fxml
root.getStylesheets().add(getClass().getResource("style.css").toExternalForm());

AFAIK在JavaFX 9中没有更简单的方法。唯一的区别是ButtonSkin已移至公开API,请参阅javafx.scene.control.skin.ButtonSkin