Класс стиля JavaFX не обновится

Я добавляю класс стилей в узел, если он выбран, и затем удаляю его, если я выбираю другой элемент. Даже если я удалю класс стиля, стиль не обновится, и он не вернется в нормальное состояние:

admin_category_label.getStyleClass().remove(admin_category_label.getStyleClass().indexOf("selected"));
admin_category_label.getStyleClass().add("clear");

но стиль останется таким же, как выбранный класс

 jewelsea04 июн. 2012 г., 23:19
В некоторых версиях JavaFX были ошибки в управлении классами стилей. Повторите тест вlate developer preview и посмотрим, есть ли у вас проблемы.

Ответы на вопрос(5)

вот более простой способ, особенно если вы не хотите возиться с другими классами:

int indexOf = textField.getStyleClass().indexOf(INVALID_CLASS);
if(indexOf != -1){
    textField.getStyleClass().remove(indexOf);
}

Почему это работает? Поскольку список, используемый для StyleClass, который является TrackableObservablieList, наследуется от иерархии, в которой удаление (индекс) вызывает изменения, а удаление (объект) - нет.

ете использовать даже 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;
}

похоже, не работает "как есть" (протестировано на 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);
    }
}

для Java 8, это работает сейчас. Но вместо того, чтобы делать то, что делал ОП, я достиг бы того же, что и этот:

admin_category_label.getStyleClass().remove("selected");
admin_category_label.getStyleClass().add("clear");

Выглядит немного чище

Помните, что ваши CSS-селекторы должны выглядеть так:

.selected {
    /* Styling attributes... */
}

.clear {
    /* Styling attributes... */
}
Решение Вопроса

Удаление класса зависших стилей, не обновляет стиль, Вы можете проголосовать и посмотреть. В качестве обходного пути вы должны переопределить правила 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 добавлен.

 11 июн. 2012 г., 19:26
@ user1236048 обновил ответ.
 11 июн. 2012 г., 18:43
Нет, вы не должны переписывать. Потому что селекторы стиля применяются один за другим в порядке их появления. Например, если я удалил style1 и не добавил style2 при нажатии кнопки, метка останется со своим стилем по умолчанию, определенным во встроенном caspian.css.
 11 июн. 2012 г., 18:46
Забудь мой предыдущий комментарий. Теперь я понял, что вы имели в виду.
 user123604811 июн. 2012 г., 18:31
Это не лучшее решение, потому что я должен переписать все правила, чтобы изменить их, они не будут автоматически сброшены до значения по умолчанию или другого класса. Но это работает. Спасибо

Ваш ответ на вопрос