Artikel-Schlagworte: „JavaFX“

Shutting down Spring backed JavaFX application

Samstag, 8. Februar 2014

This is just another short tip on how to combine JavaFX and the Spring Framework. These two technologies do not work perfectly together, but they can be made to cooperate. One of the two is the lead, meaning one is initialized first from the main method and therefore controls the lifecycle of the application. In my case this is the Spring framework as the user interface is optional. However I still want to handle the case where the user interface is closed (or the menu point quit is selected) and this should also shut down the application context of Spring.

There are three steps that should be taken:

  • Register the shutdown hooks for your application context. This has nothing to do with canceling the application in a controlled manner. This case covers things like Ctrl+C or kill -9.
((AbstractApplicationContext)context).registerShutdownHook();
  • Override the stop method of Application. When closing the application window, the stop method is called. You will want to hook into this method to signal the spring context that his end has come.
    @Override
    public void stop() throws Exception {
        System.out.println("Stopping the UI Application");

        stopUIApplicationContext();
        super.stop();
    }

In my case I used Guava’s EventBus to signal the context.

  • Finally in your code handling the context end it.
((AbstractApplicationContext)context).close();

That’s it, folks!

TextFlow with JavaFX 2

Montag, 6. Januar 2014

When ever you want to display a large portion of text in your application the Text node is your friend. Text allows you to define a wrapping width and thereby allows nice multyline text without letting you bother about the line break.

However what when your text is not that simple? It might contain portions that are differently formatted? Links? Or even icons?

JavaFX 8 has a solution for this: TextFlow. If you are however stuck with JavaFX 2 for whatever reason, there is simple workaround: pack all the Nodes into a FlowPane and define the wrapping width to be the preferred width.

public class DecoratedText extends FlowPane {

    private IntegerProperty wrappingWidth;
    private ReadOnlyObjectProperty<Font> font;
    public DecoratedText(Font font) {
        super(Orientation.HORIZONTAL);
        wrappingWidth = new SimpleIntegerProperty(this, "wrappingWidth", 0);
        getStylesheets().add(getClass().getResource(getClass().getSimpleName()+".css").toExternalForm());
        this.font = new SimpleObjectProperty<>(this, "font", font);
        prefWidthProperty().bindBidirectional(wrappingWidth);
    }

    /**
     * Append text. If the text represents a paragraph (indicated by '\n'), it
     * is not broken up into its parts.
     * @param text
     */
    public void append(String text) {
        if (text.endsWith("\n")) {
            Text decoText = new Text(text);
            //decoText.getStyleClass().add("decoratedText-text");
            decoText.setFont(font.get());
            decoText.wrappingWidthProperty().bind(wrappingWidth);
            getChildren().add(decoText);
        } else {
            String[] parts = text.split(" ");
            for (String part : parts) {
                Text decoText = new Text(part+" ");
                //decoText.getStyleClass().add("decoratedText-text");
                decoText.setFont(font.get());
                getChildren().add(decoText);
            }
        }
    }

    /**
     * Append a control.
     * @param control
     */
    public void append(Node control) {
         getChildren().add(control);
    }

    public int getWrappingWidth() {
        return wrappingWidth.get();
    }

    public IntegerProperty wrappingWidthProperty() {
        return wrappingWidth;
    }

    public void setWrappingWidth(int wrappingWidth) {
        this.wrappingWidth.set(wrappingWidth);
    }
}

The idea here is to leave text blocks which represent a paragraph by themselves as Text node. However if the paragraph contains some other node, it is splitt up into words. Thereby delegating the wrapping functionality to the underlying FlowPane.

While this solution here is not particularly sophisticated, it suffices my needs. Nevertheless I will replace it with TextFlow as soon as I migrate to Java 8.

JavaFX: Fixed size label

Freitag, 4. Januar 2013

Though JavaFX provides a component for Pagination this is based on a fixed number of pages. However consider the following use case:

You have some text of undefined length but definitely longer than can fit on a page. The text is dynamic so it is not feasible to split up the text onto several pages. Further more it may be possible that while displaying the font or the font style changes and thereby resulting in a different paging of the text.

As I have just such a use case in OpenPatrician, I did a quick test on how such a thing could be implemented.

(mehr…)

JavaFX: Perspective Transformation

Donnerstag, 3. Januar 2013

As stated in one of my previous articles, the PerspectiveTransformation is good for transforming the visual repensentation of a node/shape, but its original position still stays the same. This means that if I want an transformed area to react on events (like mouse clicks), I have to transform the coordinates and then define the position.

(mehr…)

JavaFX: Deformation with offscreen image

Mittwoch, 2. Januar 2013

As stated in my last article, I tried to render the writing part off screen to create an image off of it and then deform that.

(mehr…)