2012-06-04 9 views
9

Dodaję klasę stylu do węzła, jeśli jest ona zaznaczona, a następnie usuwam ją, jeśli wybiorę inny element. Nawet jeśli usunąć klasę styl styl przyzwyczajenie odświeżyć więc przyzwyczajenie wrócić do normalnego stanu:Klasa języka JavaFX nie będzie odświeżać

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

ale styl pozostanie taki sam jak klasy wybrany

+0

W niektórych wersjach JavaFX wystąpiły pewne błędy w zarządzaniu klasami stylów. Spróbuj ponownie wykonać test w [późnym wywiadzie dla programisty] (http://www.oracle.com/technetwork/java/javafx/downloads/devpreview-1429449.html) i sprawdź, czy nadal występują problemy. – jewelsea

Odpowiedz

15

To jest błąd. Jest to zgłaszane tutaj Removal of hovered style class, does not update styling. Możesz zagłosować i obejrzeć go. Aby obejść ten problem, należy zastąpić reguły css dotknięte/zmienione tak, aby były takie same, jak te domyślne. Demo:

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

i style.css to:

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

po kliknięciu przycisku początkowo dodanej style1 jest usuwany i style2 dodaje.

+0

To nie jest najlepsze rozwiązanie, ponieważ muszę przepisać wszystkie reguły, aby je zmienić, nie będą one automatycznie resetowane do domyślnej lub innej klasy. Ale działa. Dzięki –

+0

Nie musisz nic pisać. Ponieważ selektory stylu są stosowane jeden po drugim w kolejności, w jakiej się pojawiają. Na przykład, jeśli usunąłem styl1 i nie dodałem stylu2 przy kliknięciu przycisku, etykieta pozostaje z domyślnym stylem zdefiniowanym we wbudowanym pliku caspian.css. –

+0

Zapomnij o moim poprzednim komentarzu. Teraz rozumiem, o co ci chodziło. –

0

Można spróbować dodać css dla zamiast tego aplikacja. Możesz użyć nawet FXML do oddzielenia de design od logiki twojej aplikacji. Oto fragment kodu, który pracował dla mnie w 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; 
} 
1

Dzięki za rozwiązanie opublikowane przez Uluk Biy. Ale wydaje się nie działać "tak jak jest" (testowane na jdk 1.70_40 wygrać x 64). Muszę wyczyścić klasę stylu przed klasą ustawień. Tutaj działa dla mnie kod:

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

Przynajmniej dla Java 8, to działa teraz. Ale zamiast robić to, co OP zrobił, osiągnęłbym to samo:

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

Wygląda trochę czystszy.

Pamiętaj, że twoi selektorów CSS muszą wyglądać następująco:

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

.clear { 
    /* Styling attributes... */ 
} 
0

6 lat Laters błąd jest nadal, o to prostsze do zrobienia, szczególnie jeśli nie będzie chciał zadzierać z pozostałe klasy:

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

Dlaczego to działa? Ponieważ lista używana do StyleClass, która jest TrackableObservablieList, dziedziczy po hierarchii, w której remove (index) wywołuje zmiany, których nie usuwa (remove).

Powiązane problemy