JavaFX - 如何获取选项卡、按钮等的背景颜色

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30851893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:15:20  来源:igfitidea点击:

JavaFX - how to get background color of Tab, Button, etc

javaanimationcolorsjavafxbackground

提问by Nik Novák

Problem description:I can't get background of object in JavaFX. I don't mean Shapes, but normal Nodes like Buttons, Tabs and others. I don't know how to access to theirs background color.

问题描述:我在JavaFX中无法获取对象的背景。我指的不是形状,而是普通节点,如按钮、标签等。我不知道如何访问他们的背景颜色。

What I want?I am developing IDE and I want to run Color animation on tab with file that user want to open and is already existing in program file collection. Before doing this animation I want to read original tab background color and that color is returned to tab at the end of animation. Also I want to get back hoverand selectedproperties, which disappear when I set some color in animation and they never get back. All colors I am setting up in CSS file and I don't want to change it.

我想要的是?我正在开发 IDE,我想在选项卡上运行颜色动画,其中包含用户想要打开的文件并且已经存在于程序文件集合中。在做这个动画之前,我想阅读原始标签背景颜色,该颜色在动画结束时返回到标签。我也想找回hoverselected属性,当我在动画中设置一些颜色时它们会消失并且它们永远不会回来。我在 CSS 文件中设置的所有颜色,我不想更改它。

My question:How to get and set programmatically Node color? Or how to do color animation with save original properties and at the end of animation get this properties back?

我的问题:如何以编程方式获取和设置节点颜色?或者如何使用保存原始属性进行彩色动画并在动画结束时恢复此属性?

One short example:

一个简短的例子:

One short example

一个简短的例子

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;}

采纳答案by James_D

As far as I know, there is no way in the public API to determine what is being currently used as the background color for a Region(including for a Control) (unless you know it is either set by an inline style, in which case you can parse the result of getStyle()or by a call to setBackground(...)). But I see no reason you would want this; the color will revert to that defined in the css file if you remove any inline styles or backgroundproperty.

据我所知,在公共 API 中没有办法确定当前用作 a Region(包括 a Control)的背景颜色的内容(除非您知道它是由内联样式设置的,在这种情况下您可以解析getStyle()或通过调用setBackground(...)) 的结果。但我看不出你想要这个的理由。如果删除任何内联样式或background属性,颜色将恢复为 css 文件中定义的颜色。

Here's a simple example where the background color is set by a linear gradient (via an inline style) which slides as a task progresses:

这是一个简单的示例,其中背景颜色由线性渐变(通过内联样式)设置,该渐变随着任务的进行而滑动:

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 is almost exactly the same as you posted, but using a looked-up color instead of setting -fx-background-colordirectly:

coloured-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;
}

回答by Trunk

Can get/set Button color easy enough.

可以很容易地获取/设置按钮颜色。

Just follow the methods from Background -> BackgroundFill -> first element of getFills() list -> getFill() -- which gives you the Paint object for this node's background. Then just cast this to a Color object. The value of the Color object is listed as a hex number whose last 6 hex digitsequate to the hex RGB for that color. See output of code example below. It might be safer if I'd used the !equals(.) method rather than != for color checking but it seems to work fine anyway.

只需遵循 Background -> BackgroundFill -> getFills() 列表的第一个元素 -> getFill() 中的方法——它为您提供此节点背景的 Paint 对象。然后将其转换为 Color 对象。Color 对象的值被列为一个十六进制数字,其最后 6 个十六进制数字等于该颜色的十六进制 RGB。请参阅下面的代码示例的输出。如果我使用 !equals(.) 方法而不是 != 进行颜色检查可能会更安全,但无论如何它似乎都可以正常工作。

Say you have a checkerboard pattern of numbered 10 x 10 squares alternately colored blue or orange depending on whether the square's number is odd or even respectively. Say each square is a Button and whenever a player clicks on one of them, it is re-colored red. But if the player clicks again on the same square, it is restored to its original color.

假设您有一个编号为 10 x 10 的方格的棋盘图案,根据方格的编号是奇数还是偶数,交替着色为蓝色或橙色。假设每个方块都是一个按钮,每当玩家点击其中一个方块时,它就会重新着色为红色。但是如果玩家再次点击同一个方块,它就会恢复到原来的颜色。

Works for me.

为我工作。

.....
.....
.....

// 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 !