JavaFX - 如何获取选项卡、按钮等的背景颜色
JavaFX - how to get background color of Tab, Button, etc
问题描述:我无法在JavaFX中获取对象的背景。我指的不是形状,而是像按钮、选项卡等普通节点。我不知道如何访问他们的背景颜色。
我想要什么? 我正在开发 IDE 我想 运行 在带有用户想要打开的文件的选项卡上显示彩色动画存在于程序文件集合中。在做这个动画之前,我想阅读原始标签背景颜色,并且该颜色在动画结束时返回到标签。我还想找回 hover
和 selected
属性,当我在动画中设置一些颜色时它们会消失并且它们永远不会回来。我在 CSS 文件中设置的所有颜色,我不想更改它。
我的问题:如何以编程方式获取和设置节点颜色?或者如何通过保存原始属性来制作彩色动画并在动画结束时取回此属性?
一个简短的例子:
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="600.0" stylesheets="@style.css" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<tabs>
<Tab text="Sample tab 1">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Sample tab 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Sample tab 3">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
styles.css
.tab{
-fx-background-color: pink;}
.tab:hover{
-fx-background-color: red;}
.tab:selected{
-fx-background-color: yellow;}
据我所知,public API 无法确定当前用作 Region
背景颜色的颜色(包括 Control
)(除非您知道它是由内联样式设置的,在这种情况下您可以解析 getStyle()
的结果或通过调用 setBackground(...)
)。但我看不出你想要这个的理由;如果删除任何内联样式或 background
属性.
,颜色将恢复为 css 文件中定义的颜色
这是一个简单的示例,其中背景颜色由线性渐变(通过内联样式)设置,随着任务的进行而滑动:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ColoredTabDemo extends Application {
private int tabCount ;
@Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
for (int i = 0; i < 4; i++) {
tabPane.getTabs().add(createTab());
}
Scene scene = new Scene(tabPane, 600, 400);
scene.getStylesheets().add("colored-tab-demo.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Tab createTab() {
Tab tab = new Tab("Tab "+(++tabCount));
Button button = new Button("Load file...");
button.setOnAction(e -> {
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws Exception {
// simulate loading:
for (int i=1; i <= 500; i++) {
updateProgress(i, 500);
Thread.sleep(20);
}
return null ;
}
};
IntegerBinding progressAsPercent = Bindings.createIntegerBinding(() ->
(int) (task.getProgress() * 100), task.progressProperty());
tab.styleProperty().bind(Bindings.format("-fx-background-color: "
+ "linear-gradient(to right, -fx-accent 0%%, -fx-accent %d%%, -fx-background %1$d%%, -fx-background 100%%);",
progressAsPercent));
button.setDisable(true);
task.setOnSucceeded(evt -> {
tab.styleProperty().unbind();
tab.setStyle("");
button.setDisable(false);
});
new Thread(task).start();
});
tab.setContent(new StackPane(button));
return tab ;
}
public static void main(String[] args) {
launch(args);
}
}
colored-tab-demo.css 几乎与您发布的完全相同,但使用查找颜色而不是直接设置 -fx-background-color
:
.tab{
-fx-background-color: -fx-background;
-fx-background: pink ;
}
.tab:hover{
-fx-background: red;
}
.tab:selected{
-fx-background: yellow;
}
可以get/set按钮颜色足够简单。
只需遵循 Background -> BackgroundFill -> getFills() 列表的第一个元素 -> getFill() 中的方法——这将为您提供此节点背景的 Paint 对象。
然后将其转换为 Color 对象。
Color 对象的值以十六进制数字的形式列出,其 最后 6 个十六进制数字 等于该颜色的十六进制 RGB。请参阅下面的代码示例的输出。
如果我使用 !equals(.) 方法而不是 != 进行颜色检查可能会更安全,但它似乎工作正常。
假设您有一个棋盘图案,其中包含编号为 10 x 10 的方块,颜色交替为蓝色或橙色,具体取决于方块的编号是奇数还是偶数。
假设每个方块都是一个按钮,每当玩家点击其中一个时,它就会重新变成红色。
但是如果玩家再次点击同一个方块,它会恢复到原来的颜色。
适合我。
.....
.....
.....
// Declare click response :
playBoard[i][j].setOnAction(e ->
{
n = Integer.parseInt(((Button)e.getSource()).getText());
toggleColorButtonRed((Button)e.getSource(), n);
});
.....
.....
.....
private void toggleColorButtonRed(Button button, int n)
{
Color color = (Color)button.getBackground().getFills().get(0).getFill();
if (color != Color.RED)
button.setBackground(new Background(new BackgroundFill(
Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
else
{
System.out.println("You have clicked a " + color + " square !");
if (n % 2 == 0)
button.setBackground(new Background(new BackgroundFill(
Color.ORANGE, CornerRadii.EMPTY, Insets.EMPTY)));
else
button.setBackground(new Background(new BackgroundFill(
Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
}
OUTPUT WHEN A SQUARE IS CLICKED TWICE
=====================================
You have clicked a 0xff0000ff square !
问题描述:我无法在JavaFX中获取对象的背景。我指的不是形状,而是像按钮、选项卡等普通节点。我不知道如何访问他们的背景颜色。
我想要什么? 我正在开发 IDE 我想 运行 在带有用户想要打开的文件的选项卡上显示彩色动画存在于程序文件集合中。在做这个动画之前,我想阅读原始标签背景颜色,并且该颜色在动画结束时返回到标签。我还想找回 hover
和 selected
属性,当我在动画中设置一些颜色时它们会消失并且它们永远不会回来。我在 CSS 文件中设置的所有颜色,我不想更改它。
我的问题:如何以编程方式获取和设置节点颜色?或者如何通过保存原始属性来制作彩色动画并在动画结束时取回此属性?
一个简短的例子:
sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<TabPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="480.0" prefWidth="600.0" stylesheets="@style.css" tabClosingPolicy="UNAVAILABLE" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<tabs>
<Tab text="Sample tab 1">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Sample tab 2">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Sample tab 3">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
styles.css
.tab{
-fx-background-color: pink;}
.tab:hover{
-fx-background-color: red;}
.tab:selected{
-fx-background-color: yellow;}
据我所知,public API 无法确定当前用作 Region
背景颜色的颜色(包括 Control
)(除非您知道它是由内联样式设置的,在这种情况下您可以解析 getStyle()
的结果或通过调用 setBackground(...)
)。但我看不出你想要这个的理由;如果删除任何内联样式或 background
属性.
这是一个简单的示例,其中背景颜色由线性渐变(通过内联样式)设置,随着任务的进行而滑动:
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.IntegerBinding;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class ColoredTabDemo extends Application {
private int tabCount ;
@Override
public void start(Stage primaryStage) {
TabPane tabPane = new TabPane();
for (int i = 0; i < 4; i++) {
tabPane.getTabs().add(createTab());
}
Scene scene = new Scene(tabPane, 600, 400);
scene.getStylesheets().add("colored-tab-demo.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private Tab createTab() {
Tab tab = new Tab("Tab "+(++tabCount));
Button button = new Button("Load file...");
button.setOnAction(e -> {
Task<Void> task = new Task<Void>() {
@Override
public Void call() throws Exception {
// simulate loading:
for (int i=1; i <= 500; i++) {
updateProgress(i, 500);
Thread.sleep(20);
}
return null ;
}
};
IntegerBinding progressAsPercent = Bindings.createIntegerBinding(() ->
(int) (task.getProgress() * 100), task.progressProperty());
tab.styleProperty().bind(Bindings.format("-fx-background-color: "
+ "linear-gradient(to right, -fx-accent 0%%, -fx-accent %d%%, -fx-background %1$d%%, -fx-background 100%%);",
progressAsPercent));
button.setDisable(true);
task.setOnSucceeded(evt -> {
tab.styleProperty().unbind();
tab.setStyle("");
button.setDisable(false);
});
new Thread(task).start();
});
tab.setContent(new StackPane(button));
return tab ;
}
public static void main(String[] args) {
launch(args);
}
}
colored-tab-demo.css 几乎与您发布的完全相同,但使用查找颜色而不是直接设置 -fx-background-color
:
.tab{
-fx-background-color: -fx-background;
-fx-background: pink ;
}
.tab:hover{
-fx-background: red;
}
.tab:selected{
-fx-background: yellow;
}
可以get/set按钮颜色足够简单。
只需遵循 Background -> BackgroundFill -> getFills() 列表的第一个元素 -> getFill() 中的方法——这将为您提供此节点背景的 Paint 对象。 然后将其转换为 Color 对象。 Color 对象的值以十六进制数字的形式列出,其 最后 6 个十六进制数字 等于该颜色的十六进制 RGB。请参阅下面的代码示例的输出。 如果我使用 !equals(.) 方法而不是 != 进行颜色检查可能会更安全,但它似乎工作正常。
假设您有一个棋盘图案,其中包含编号为 10 x 10 的方块,颜色交替为蓝色或橙色,具体取决于方块的编号是奇数还是偶数。 假设每个方块都是一个按钮,每当玩家点击其中一个时,它就会重新变成红色。 但是如果玩家再次点击同一个方块,它会恢复到原来的颜色。
适合我。
.....
.....
.....
// Declare click response :
playBoard[i][j].setOnAction(e ->
{
n = Integer.parseInt(((Button)e.getSource()).getText());
toggleColorButtonRed((Button)e.getSource(), n);
});
.....
.....
.....
private void toggleColorButtonRed(Button button, int n)
{
Color color = (Color)button.getBackground().getFills().get(0).getFill();
if (color != Color.RED)
button.setBackground(new Background(new BackgroundFill(
Color.RED, CornerRadii.EMPTY, Insets.EMPTY)));
else
{
System.out.println("You have clicked a " + color + " square !");
if (n % 2 == 0)
button.setBackground(new Background(new BackgroundFill(
Color.ORANGE, CornerRadii.EMPTY, Insets.EMPTY)));
else
button.setBackground(new Background(new BackgroundFill(
Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
}
}
OUTPUT WHEN A SQUARE IS CLICKED TWICE
=====================================
You have clicked a 0xff0000ff square !