0

When I include the path to css resources in the JavaFx Application class the project runs perfectly.

public class SampleApp extends Application {

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

    @Override
    public void start(Stage stage) throws Exception {
        AnnotationConfigApplicationContext context
                = new AnnotationConfigApplicationContext(SampleAppFactory.class);

        SampleController sampleController = context.getBean(SampleController.class);
        Scene scene = new Scene((Parent) sampleController.getView(), 320, 240);
        scene.getStylesheets().add("/resources/css/fxmlapp.css");

        stage.setScene(scene);
        stage.setTitle("JFX2.0 Sprung");
        stage.show();
    }
}

However, it fails to complile when I include the css path in the FXML file.

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane fx:id="view" prefHeight="98.0" prefWidth="160.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.rev.SampleController">
  <children>
    <Button fx:id="printBtn" onAction="#print" text="Click Me" />
  </children>
  <stylesheets>
    <URL value="@../css/fxmlapp.css" />
  </stylesheets>
</StackPane>

Note the inclussion on the line <URL value="@../css/fxmlapp.css" />.

I'd like to work with the css included in the FXML since it is much easier to design the FXML with the css there, you know - you can see how a particular css property affects a page's look and feel. How can I go about to make it work? Thank you all.

The other classes are as follows:

@Configuration
public class SampleAppFactory {

    @Bean
    public Person person() {
        return new Person("Richard");
    }

    @Bean
    public SampleController sampleController() throws IOException {
        return (SampleController) loadController("/resources/fxml/Sample.fxml");
    }

    protected Object loadController(String url) throws IOException {
        InputStream fxmlStream = null;
        try {
            fxmlStream = getClass().getResourceAsStream(url);
            FXMLLoader loader = new FXMLLoader();
            loader.load(fxmlStream);
            return loader.getController();
        } finally {
            if (fxmlStream != null) {
                fxmlStream.close();
            }
        }
    }
}

public class SampleController {

    @FXML
    private Node view;
    @Autowired
    private Person person;

    public Node getView() {
        return view;
    }

    public Person getPerson() {
        return person;
    }

    public void print(ActionEvent event) {
        System.out.println("Well done, " + person.getFirstName() + "!");
    }
}

The file: fxmlapp.css


.root {
    -fx-background-color: linear-gradient(from 0% 0% to 0% 100%, #cbd0d7 0%, white 100%);
}

#printBtn {
    -fx-text-fill: #e4f3fc;
    -fx-font: 20pt "Tahoma Bold";
    -fx-padding: 10;
    -fx-base: #2d4b8e
}

#printBtn:hover{
    -fx-base: #395bae;
}

1 Answer 1

1

Use the a java.net.URL instead of an InputStream, e.g. as follows:

protected Object loadController(String url) throws IOException {
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource(url));
        loader.load();
        return loader.getController();
    }
    catch(...) {...}
}

This way the FXML mechanism will be able to resolve the relative URI.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much @Nikos Paraskevopoulos. That works perfect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.