2012-06-04 10 views
9

Ich füge einem Knoten eine Stilklasse hinzu, wenn sie ausgewählt ist, und entferne sie dann, wenn ich ein anderes Element auswähle. Auch wenn ich den Stil pflegt den Stil Klasse entfernen aktualisieren, so werden es nicht in den normalen Zustand zurück:Die JavaFX-Stilklasse wird nicht aktualisiert.

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

aber der Stil ist der gleiche wie Klasse ausgewählt

+0

In einigen JavaFX-Versionen gab es einige Fehler in der Stilklassenverwaltung. Versuchen Sie Ihren Test erneut in einer [späte Entwicklervorschau] (http://www.oracle.com/technetwork/java/javafx/downloads/devpreview-1429449.html) und prüfen Sie, ob weiterhin Probleme auftreten. – jewelsea

Antwort

15

Dies ist ein Fehler. Es wird hier berichtet Removal of hovered style class, does not update styling. Vielleicht möchten Sie abstimmen und es sehen. Als Workaround sollten Sie CSS-Regeln überschreiben, die Sie berührt/geändert haben, um dieselben wie die Standardregeln zu sein. 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); 
    } 
} 

und die style.css ist:

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

, wenn die Schaltfläche die anfangs angeklickt wird hinzugefügt style1 entfernt wird und die style2 hinzugefügt wird.

+0

Es ist nicht die beste Lösung, weil ich alle Regeln neu schreiben muss, um sie zu ändern, sie werden nicht automatisch auf Standard oder andere Klasse zurückgesetzt. Aber es funktioniert. Danke –

+0

Nein, du musst nicht umschreiben. Die Stilauswahl wird nacheinander in der Reihenfolge angewendet, in der sie angezeigt werden. Zum Beispiel, wenn ich das style1 entfernt habe und nicht das style2 bei einem Klick auf die Schaltfläche hinzugefügt habe, bleibt das Label mit seinem Standardstil, der in der eingebauten caspian.css definiert ist. –

+0

Vergiss meinen vorherigen Kommentar. Ich verstehe jetzt, was Sie meinen. –

0

Sie bleiben können versuchen, einen CSS für das hinzufügen Anwendung stattdessen. Sie können sogar FXML verwenden, um das Design von der Logik Ihrer Anwendung zu trennen. Hier ist ein Code, der in JavaFX 2.1 für mich funktioniert hat!

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

Danke für die Lösung von Uluk Biy geschrieben. Aber es scheint nicht "so wie es ist" zu funktionieren (getestet auf jdk 1.70_40 win x 64). Ich muss die Stilklasse vor den Einstellungen deaktivieren. Hier der Arbeitscode für mich:

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

Zumindest für Java 8, das funktioniert jetzt. Aber anstatt zu tun, was das OP tat, würde ich das gleiche wie folgt erreichen:

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

Sieht ein bisschen sauberer aus.

Denken Sie daran, dass Ihre CSS-Selektoren wie folgt aussehen müssen:

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

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

6 Jahre laters der Fehler ist immer noch da, hier ist ein einfacher Weg, speziell zu gehen, wenn Sie nicht zu verwirren wollen mit die anderen Klassen:

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

Warum funktioniert das? Da die für StyleClass verwendete Liste, bei der es sich um eine TrackableObservablieList handelt, von einer Hierarchie erbt, bei der das Entfernen (Index) Änderungen auslöst, bei denen das Entfernen (Objekt) nicht erfolgt.