JavaFX wie funktioniert CSS und javaFX

strußi

Top Contributor
Moin,
IDE:Netbeans 8.2
JDK:1.8.0_102

ich habe das Standard "Hello World" von NetBeans. Ziel ist es jetzt herauszubekommen wie ich den Button ein "Dark-Thema" mittels CSS verpassen kann.
CSS:
#button {
    -fx-color: black;
    -fx-background-color: black;
    -fx-fill: thistle;
    -fx-border-color: thistle;
}
Java:
package csstest;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
*
* @author user
*/
public class CssTest extends Application{
  
    @Override
    public void start( Stage primaryStage ){
        Button btn = new Button();
        btn.setId( "button");
        btn.setText( "Say 'Hello World'" );
        btn.setOnAction(( ActionEvent event ) -> {
            System.out.println( "Hello World!" );
        });
      
        StackPane root = new StackPane();
        root.getChildren().add( btn );
      
        Scene scene = new Scene(root, 300, 250 );
        primaryStage.setTitle( "Hello World!" );
        primaryStage.setScene( scene );
        scene.getStylesheets().add( "Dark.css");
      
      
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main( String[] args ){
        launch( args );
    }
  
}
css und java-Datei liegen im gleichen Package
Das Programm läuft zwar durch und das Fenster öffnet sich auch aber der CSS-File wird nicht angewendet weil die Resource nicht gefunden wird.

-- log
ant -f C:\\Users\\user\\Documents\\NetBeansProjects\\CssTest -Djavac.includes=csstest/CssTest.java -Dnb.internal.action.name=run.single -Drun.class=csstest.CssTest run-single
init:
Deleting: C:\Users\user\Documents\NetBeansProjects\CssTest\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\user\Documents\NetBeansProjects\CssTest\build\built-jar.properties
Compiling 1 source file to C:\Users\user\Documents\NetBeansProjects\CssTest\build\classes
compile-single:
run-single:
Nov 07, 2016 3:21:49 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "Dark.css" not found.
BUILD SUCCESSFUL (total time: 4 seconds)

viele Grüße
 
Ungeachtet davon, wie Netbeans mit der Verzeichnisstruktur umgeht, versuch doch zunächst mithilfe des nachfolgenden Codeschnipsels zu debuggen, wo du dich überhaupt befindest bzw. was aktuell alles in deinem Verzeichnis an Dateien liegt:

Code:
File file = new File(".");
for(File child: file.listFiles())
System.out.println(child.getName());

damit wirst du schonmal rausfinden, ob deine CSS-Datei überhaupt in deinem Verzeichnis liegt, auf das du zugreifen möchtest.
Was ich jedoch glaube ist, dass er die Dark.css-Datei, wenn du sie so wie bei dir einbindest, dass er sie über das Verzeichnis wo deine Jar-Datei liegt einbindet, statt aus deinem Jar-Archiv selbst. Probier als zweiten Anlauf also einmal, die Jar-Datei in ein Verzeichnis zu legen bzw. leg die CSS-Datei einfach zur Jar-Datei dazu, dann sollte es gehen.

Ich halte alle FXML/CSS/Bild-Dateien im Resources-Verzeichnis unter src/main/resources, dann werden die Dateien mit in die Jar gepackt beim Bauen und du kannst mithilfe getClass().getResource(...) eine Url mit reinladen. Generell solltest du deine CSS-Dateien auch in der FXML mit einbinden statt im Code, das vereinfacht in erster Linie die Trennung zwischen deiner GUI und deinem Code.
 
Dann siehst du hieran, dass die Dateiangabe zum Dark.css nicht ausreicht, sondern du noch weiter bis zu dem Package navigieren musst. Die Pfadangabe sollte also aussehen wie "src/main/java/deinpackagepfad/Dark.css"
 
ich habe jetzt alle Varianten, von
scene.getStylesheets().add( "C:\\Users\\user\\Documents\\NetBeansProjects\\CssTest\\src\\csstest\\Dark.css" ); bis
scene.getStylesheets().add( "csstest/Dark.css" );
ausprobiert
die Ausgabe war immer dieselbe
ant -f C:\\Users\\user\\Documents\\NetBeansProjects\\CssTest -Djavac.includes=csstest/CssTest.java -Dnb.internal.action.name=run.single -Drun.class=csstest.CssTest run-single
init:
Deleting: C:\Users\user\Documents\NetBeansProjects\CssTest\build\built-jar.properties
deps-jar:
Updating property file: C:\Users\user\Documents\NetBeansProjects\CssTest\build\built-jar.properties
Compiling 1 source file to C:\Users\user\Documents\NetBeansProjects\CssTest\build\classes
compile-single:
run-single:
Nov 07, 2016 9:22:19 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "src/csstest/Dark.css" not found.
BUILD SUCCESSFUL (total time: 5 seconds)

nur mit dem Unterschied in dem Resource-Pfad.

Kann es sein, das ich etwas generelles überseh?
 
Also als allererstes:
wie funktioniert CSS und javaFX
Antwort: Gut! 😀

Zu deinem Problem
Java:
scene.getStylesheets().add( "Dark.css");

Hier mal die JavaDoc
public final ObservableList<String> getStylesheets()
Gets an observable list of string URLs linking to the stylesheets to use with this scene's contents.
The URL is a hierarchical URI of the form [scheme:][//authority][path]. If the URL does not have a [scheme:] component, the URL is considered to be the [path] component only. Any leading '/' character of the [path] is ignored and the [path] is treated as a path relative to the root of the application's classpath.

package com.example.javafx.app;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class MyApp extends Application {

@Override public void start(Stage stage) {
Scene scene = new Scene(new Group());
scene.getStylesheets().add("/com/example/javafx/app/mystyles.css");
stage.setScene(scene);
stage.show();
}

public static void main(String[] args) {
launch(args);
}
}

For additional information about using CSS with the scene graph, see the CSS Reference Guide.
Was lernen wir?
1) Es verlangt eine URL ODER
2) einen Pfad im Classpath.
3) dein Code muss wie folgt aussehen (vorausgesetzt, dass die Datei Dark.css am Ende auch im JAR enthalten ist, oder wenn du das .class-File ausführst, dass die Datei daneben liegt und in den Classpath aufgenommen wurde - was NetBeans auch machen sollte)
Java:
scene.getStylesheets().add(getClass().getResource("/Dark.css"));
(wobei der Slash "/" am Anfang laut Doku auch weggelassen werden kann)

#edit: die Variante
Java:
getClass().getResource("")
nutze ich meist, damit ich sicher bin, dass ein ordentlicher Pfad draus wird. Ich geh da gerne auch Nummer sicher und es funktioniert so bei mir in diversen Anwendungen.
 
hi, die Variante scene.getStylesheets().add(getClass().getResource("/Dark.css")); hatte ich auch schon gesehen und ausprobiert, mit dem Resultat, could not find Resource
 
Dann solltest du wirklich mal überprüfen, ob die Dark.css denn überhaupt dort liegt, wo sie sein sollte: Neben dem Class-File!
 
Hallo dzim,

das Problem habe ich auch, das beim Compilieren, dass die CSS Dateien nicht in das Binary Verzeichnis kopiert werden. Kann man das irgendwo in Eclipse konfigurieren? Ich habe die css einfach in das Bin Verzeichnis gelegt.

Grüße
lam
 
Hm. Bei mir klappt es immer. Ich müsste dazu deine Projektstruktur kennen (Pfadstruktur).
Wie arbeitest du? Mit Maven? Oder erstellst du "nur" e(fx)clipse-Projekte?
Ich habe bereits eine ganze Batterie an verschiedenen Projekten gemacht. Wichtig war für alle (jedenfalls für mich persönlich), das ich das e(fx)clipse-Plugin nutzen konnte. Damit hat alles geklappt...
 
Axo, nee ich habe ein JavaProject angelegt und in dem Project ist ein css/default.css Datei.
Und speziell das Css Verzeichnis habe ich in den Classpath hinzugefügt.
 
wenn du in einen normalen Projekt im src-Verzeichniss ein Package "css" anlegst und da dein File rein tust, sollte das automatisch Teil des Classpath sein. Alles ausserhalb des src musst du selbst einbinden, wenn du es benötigst.
Ich denke mal, dass es bei NetBeans nicht anders ist...
 
Ja genau, aber ich habe in dem Fall ein separates Verzeichnis außerhalb des src Verzeichnis, aber selbst mit Classpath Einbindung, hatte die IDE nicht ordnungsgemäß ins Bin kopiert.
 
Ich würde dir e(fx)clipse ans Herz legen. Und dann erstell ein JavaFX-Projekt. Das macht alles so, dass es funktioniert...
 
Hallo,
besteht das Problem mit CSS immer noch?

Wenn ja, hast du es mal auch so probiert?
Code:
this.getClass().getResource("/styles/Dark.css").toExternalForm()
LG Dominic
 
Ja, hat er wohl. Wenn ich es richtig verstehe, ist sein CSS eifach nicht im ClassPath und somit nicht per getClass().getResource("...") auffindbar...
Irgendetwas muss an seinem Projekt-Setup schief sein.
 
Mhm, okay stimmt. Da das Projekt ja noch mir noch nicht soo groß erscheint, könnte man versuchen einfach mit Netbeans mal ein neues JavaFX-Projekt zu erstellen und den Quellcode da hinein zu pasten. Normalerweise funktioniert es, wenn die CSS-Datei im selben Ordner liegt zum Beispiel mit der Zeile hier:
Code:
scene.getStylesheets().add(this.getClass().getResource("Dark.css").toExternalForm());
 
Ja. Er verwendet zwar Eclipse, aber auch dort gibt es, wenn man das entsprechende Plugin kurz nachinstalliert hat, spezifische JavaFX-Projekte. Und das funktioniert. Habe mit dem Plugin in seinen frühesten und hässlichsten Stunden auf Eclipse noch mit dem separat herunterzuladenen JavaFX begonnen, auf dieses Framework umzusteigen. Und nie grossartige Probleme damit.
 

Zurück
Oben