JavaFX 样式类不会刷新
Posted
技术标签:
【中文标题】JavaFX 样式类不会刷新【英文标题】:JavaFX style class won't refresh 【发布时间】:2012-06-08 21:26:25 【问题描述】:如果节点被选中,我将添加一个样式类,如果我选择其他项目,则将其删除。即使我删除了样式类,样式也不会刷新,所以它不会回到正常状态:
admin_category_label.getStyleClass().remove(admin_category_label.getStyleClass().indexOf("selected"));
admin_category_label.getStyleClass().add("clear");
但样式将保持与所选类相同
【问题讨论】:
在一些 JavaFX 版本中存在一些围绕样式类管理的错误。在late developer preview 中重试您的测试,看看您是否还有问题。 【参考方案1】:这是一个错误。此处报道Removal of hovered style class, does not update styling。您可能想投票并观看它。作为一种解决方法,您应该覆盖您触摸/更改为与默认规则相同的 css 规则。演示:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBoxBuilder;
import javafx.stage.Stage;
public class StyleDemo extends Application
@Override
public void start(Stage primaryStage)
final Label lbl = new Label("Style Me");
lbl.getStyleClass().add("style1"); // initial style
Button btn = new Button("Change the style");
btn.setOnAction(new EventHandler<ActionEvent>()
@Override
public void handle(ActionEvent arg0)
lbl.getStyleClass().remove("style1");
lbl.getStyleClass().add("style2");
);
StackPane root = new StackPane();
root.getChildren().add(VBoxBuilder.create().spacing(20).children(lbl, btn).build());
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add(this.getClass().getResource("style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
public static void main(String[] args)
launch(args);
style.css 是:
.style1
-fx-text-fill: red;
-fx-border-color: green;
-fx-font-size: 20;
.style2
-fx-text-fill: blue;
-fx-border-color: red;
-fx-font-size: 15;
-fx-underline: true;
当点击按钮时,最初添加的style1
被删除,style2
被添加。
【讨论】:
这不是最好的解决方案,因为我必须重写所有规则来更改它们,它们不会自动重置为默认值或其他类。但它有效。谢谢 不,你不必重写。因为样式选择器是按照它们出现的顺序一个接一个地应用的。例如,如果我删除了 style1 并且没有在单击按钮时添加 style2,那么标签将保持其在内置 caspian.css 中定义的默认样式。 忘记我之前的评论。我现在明白你的意思了。【参考方案2】:感谢 Uluk Biy 发布的解决方案。但它似乎不能“按原样”工作(在 jdk 1.70_40 win x 64 上测试)。我必须在设置类之前清除样式类。这是我的工作代码:
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBoxBuilder;
import javafx.stage.Stage;
public class StyleDemo extends Application
//ADD just a toggle property
public static BooleanProperty toggle = new SimpleBooleanProperty(false);
@Override
public void start(Stage primaryStage)
final Label lbl = new Label("Style Me");
lbl.getStyleClass().add("style1"); // initial style
Button btn = new Button("Change the style");
btn.setOnAction(new EventHandler<ActionEvent>()
@Override
public void handle(ActionEvent event)
//ADD clear style class !
lbl.getStyleClass().clear();
if(toggle.get())
lbl.getStyleClass().add("style1");
toggle.set(!toggle.get());
else
lbl.getStyleClass().add("style2");
toggle.set(!toggle.get());
);
StackPane root = new StackPane();
root.getChildren().add(VBoxBuilder.create().spacing(20).children(lbl,btn).build());
Scene scene = new Scene(root, 300, 250);
scene.getStylesheets().add("/style.css");
primaryStage.setScene(scene);
primaryStage.show();
public static void main(String[] args)
launch(args);
【讨论】:
【参考方案3】:至少对于 Java 8,现在可以使用。但是,我不会像 OP 那样做,而是像这样实现同样的目标:
admin_category_label.getStyleClass().remove("selected");
admin_category_label.getStyleClass().add("clear");
看起来有点干净。
请记住,您的 CSS 选择器需要如下所示:
.selected
/* Styling attributes... */
.clear
/* Styling attributes... */
【讨论】:
【参考方案4】:6 年后,该错误仍然存在,这是一种更简单的方法,特别是如果您不想与其他类混淆:
int indexOf = textField.getStyleClass().indexOf(INVALID_CLASS);
if(indexOf != -1)
textField.getStyleClass().remove(indexOf);
为什么这样有效?因为用于 StyleClass 的列表是 TrackableObservablieList 继承自 remove(index) 确实触发了 remove(Object) 没有的更改的层次结构。
【讨论】:
【参考方案5】:您可以尝试为应用程序添加一个 CSS。您甚至可以使用 FXML 将设计与应用程序的逻辑分开。这是一段在 JavaFX 2.1 中对我有用的代码!
private Parent replaceSceneContent(String fxml) throws Exception
Parent page = (Parent)
FXMLLoader.load(
Main.class.getResource(fxml), null, new JavaFXBuilderFactory());
Scene scene = stage.getScene();
if (scene == null)
scene = new Scene(page, 1366, 720);
scene.getStylesheets().add(
Main.class.getResource(
"../skinFolder/css/defaultSkin.css" ).toExternalForm());
stage.setScene(scene);
else
stage.getScene().setRoot(page);
stage.sizeToScene();
return page;
【讨论】:
以上是关于JavaFX 样式类不会刷新的主要内容,如果未能解决你的问题,请参考以下文章