16

我有一个带有这段代码的简单场景:

scene.getStylesheets().add("packagename/testcss.css");

我的 testcss.css 是:

.button { 
    -fx-background-color: #DDFFA4;
}

.button:hover {
    -fx-background-color: #9ACD32;
}

我实现的是在 Web 应用程序中也就是悬停的漂亮效果。

在此处输入图像描述 ... 在此处输入图像描述

问题
我怎样才能实现相同的效果,但没有单独的 css 文件,只需通过我的 Button 的 setStyle 方法?
问题是 setStyle 只接受样式定义而忽略了选择器。

button.setStyle("-fx-background-color: #DDFFA4;");

选择器,在我的悬停情况下是伪类:

.button:hover

但我应该在哪里设置它?

此外,javadoc 明确地从 setStyle 方法参数中排除了选择器:

请注意,与 HTML 样式属性一样,此变量包含样式属性和值,而不是样式规则的选择器部分。

4

2 回答 2

30

正如您在问题中指出的那样,从 JavaFX 2.2 开始,css 伪类不会作为公共 API 的一部分公开,您可以将其用于 Java 代码中的样式操作。

如果您想在不使用样式表的情况下从 Java 代码更改样式属性,则需要根据事件或更改侦听器设置样式。下面的示例中有几个选项。

import javafx.application.Application;
import javafx.beans.binding.*;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.stage.Stage;

/** Changing button styles on hover without a css stylesheet. */
public class ButtonBackgroundChanger extends Application {
  private static final String STANDARD_BUTTON_STYLE = "-fx-background-color: #DDFFA4;";
  private static final String HOVERED_BUTTON_STYLE  = "-fx-background-color: #9ACD32;";

  public static void main(String[] args) throws Exception { launch(args); }
  @Override public void start(final Stage stage) throws Exception {
    Button configure = new Button("Configure");
    changeBackgroundOnHoverUsingBinding(configure);
    Button update = new Button("Update");
    changeBackgroundOnHoverUsingEvents(update);

    VBox layout = new VBox(10);
    layout.setAlignment(Pos.CENTER);
    layout.setStyle("-fx-padding: 10;");
    layout.getChildren().addAll(configure, update);
    stage.setScene(new Scene(layout));
    stage.show();
  }

  private void changeBackgroundOnHoverUsingBinding(Node node) {
    node.styleProperty().bind(
      Bindings
        .when(node.hoverProperty())
          .then(
            new SimpleStringProperty(HOVERED_BUTTON_STYLE)
          )
          .otherwise(
            new SimpleStringProperty(STANDARD_BUTTON_STYLE)
          )
    );
  }

  public void changeBackgroundOnHoverUsingEvents(final Node node) {
    node.setStyle(STANDARD_BUTTON_STYLE);
    node.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        node.setStyle(HOVERED_BUTTON_STYLE);
      }
    });
    node.setOnMouseExited(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent mouseEvent) {
        node.setStyle(STANDARD_BUTTON_STYLE);
      }
    });
  }    
}

如果颜色需要真正动态地使用具有预定义颜色和样式的样式表存在问题,或者如果对使用 css 样式表有一些其他厌恶,我只会在代码而不是样式表中真正做到这一点。

在 JavaFX 8 中有一个公共 API,它允许您(如果您愿意)在不使用 CSS 的情况下操作区域背景颜色

示例程序输出(更新按钮悬停):

示例程序输出

于 2012-10-25T19:53:54.347 回答
1

您可以选择将它们设置为 css 以在触发不同事件时以编程方式更改/更新。我针对我的签入按钮将以下函数添加到 fxml 文件事件中。

 @FXML
    private void onHover(MouseEvent event)
    {
        if(btnCheckin.getText().contentEquals("Check Out"))
        {
            btnCheckin.setStyle("-fx-font-size: 20; -fx-font-weight: bold; -fx-padding: -5 -5 -5 -5;   \n" +
                            "    -fx-border-color: #e2e2e2;\n" +
                            "    -fx-border-width: 2;\n" +
                            "    -fx-border-radius: 5;\n" +
                            "    -fx-background-radius: 5;\n" +
                            "    -fx-background-color: #3a3a3a;\n" +
                            "    -fx-font-family: \"Lato Bold\", Helvetica, Arial, sans-serif;\n" +
                            "    -fx-text-fill: white;\n" +
                            "    -fx-background-insets: 0 0 0 0, 0, 1, 2;");
        }
    }

    @FXML
    private void onExit(MouseEvent event)
    {
        if(btnCheckin.getText().contentEquals("Check Out"))
        {
            btnCheckin.setStyle("-fx-font-size: 20; -fx-font-weight: bold; -fx-padding: -5 -5 -5 -5;   \n" +
                            "    -fx-border-width: 2;\n" +
                            "    -fx-border-radius: 5;\n" +
                            "    -fx-background-radius: 5;\n" +
                            "    -fx-font-family: \"Lato Bold\", Helvetica, Arial, sans-serif;\n" +
                            "    -fx-text-fill: white;\n" +
                            "    -fx-background-insets: 0 0 0 0, 0, 1, 2;\n" +
                            "    -fx-background-color: #EE6559;\n" +
                            "    -fx-border-color: #EE6559;");
        }
    }

    @FXML
    private void onPress(MouseEvent event)
    {
        if(btnCheckin.getText().contentEquals("Check Out"))
        {
            btnCheckin.setStyle("-fx-font-size: 20; -fx-font-weight: bold; -fx-padding: -5 -5 -5 -5;   \n" +
                            "    -fx-border-color: #e2e2e2;\n" +
                            "    -fx-border-width: 2;\n" +
                            "    -fx-border-radius: 5;\n" +
                            "    -fx-background-radius: 5;\n" +
                            "    -fx-background-color: white;\n" +
                            "    -fx-font-family: \"Lato Bold\", Helvetica, Arial, sans-serif;\n" +
                            "    -fx-text-fill: #1d1d1d;\n" +
                            "    -fx-background-insets: 0 0 0 0, 0, 1, 2;");
        }
    }

    @FXML
    private void onRelease(MouseEvent event)
    {
        if(btnCheckin.getText().contentEquals("Check Out"))
        {
            onHover(event);
        }
    }
于 2018-12-28T18:10:14.210 回答