FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

A Short Tour Through JavaFX-UI-Common

A Short Tour Through JavaFX-UI-Common

We’ve just recently announced the release of the “javafx-ui-common” project into OpenJFX. The name may be a little underwhelming, but the content is absolutely core to JavaFX. For most developers interested in contributing to JavaFX and in understanding how the system works, javafx-ui-common and javafx-ui-controls will be the two most important projects, both of which are now open source, and are part of the “JavaFX Public API” shown in the diagram. For developers interested in porting JavaFX to other platforms or improving the graphics performance — well we will be open sourcing Prism and Glass in the next few months :-).

Since javafx-ui-common is such a foundational part of the JavaFX platform, I thought I should give a short tour of what is in there, including the (gasp!) non-public portions. As always, non-public API (or rather, unsupported API, meaning anything that is not in the javafx namespace such as com.sun.*) cannot be depended on from release to release. But for those of you wondering how things work, there is some very important stuff buried in the unsupported packages, and for those of you wanting to actually hack on OpenJFX, this will be of even greater interest. If you haven’t yet, you might want to brush up on the overall architecture with this article.

In fact, our tour will begin in the unsupported package, with the Toolkit class, which you see as the second layer in the above diagram. This article is of interest to anybody wanting to work on JavaFX itself.

(more…)

ToolBar in FXML No Longer Requires tag

While writing the last blog post on segmented buttons, I found a bug (or rather, a feature missing from ToolBar). I had to use the following FXML:

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

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

<BorderPane id="background" prefWidth="800.0" prefHeight="600.0" xmlns:fx="http://javafx.com/fxml">
    <top>
        <ToolBar>
            <items>
                <Region styleClass="spacer" />
                <HBox styleClass="segmented-button-bar">
                    <Button text="Tasks" styleClass="first" />
                    <Button text="Administrator" />
                    <Button text="Search" />
                    <Button text="Line" />
                    <Button text="Process" styleClass="last" />
                </HBox>
            </items>
        </ToolBar>
    </top>
</BorderPane>

You will notice that the ToolBar required the <items> element for adding the, well, items to the ToolBar. This extra level of verbosity was just asking to be smashed. I filed & fixed & Greg reviewed the fix for RT-19476. As of a few minutes ago, this fix has gone into the control’s scrum forest and should be making its way into the next weekly build. So now, you can just say:

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

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

<BorderPane id="background" prefWidth="800.0" prefHeight="600.0" xmlns:fx="http://javafx.com/fxml">
    <top>
        <ToolBar>
            <Region styleClass="spacer" />
            <HBox styleClass="segmented-button-bar">
                <Button text="Tasks" styleClass="first" />
                <Button text="Administrator" />
                <Button text="Search" />
                <Button text="Line" />
                <Button text="Process" styleClass="last" />
            </HBox>
        </ToolBar>
    </top>
</BorderPane>

It’s the little things in life, really 😉

Customized Segmented ToolBar Buttons

Customized Segmented ToolBar Buttons

One of Jasper’s favorite websites is called Dribbble, which is a place for designers to post whatever work they’re currently working on for others to view and be inspired from. I got hooked on Dribbble last Thursday and have been looking at a bunch of the mockups and itching to try implementing some of them in JavaFX. Here is my first attempt.

One of the use cases we used for our CSS support and our ToolBar API was that we wanted to support a style of toolbar button which (at least for me) was popularized on the Mac, which is referred to by Cocoa as a “segmented” button. This is essentially nothing more than an HBox of buttons that has been styled such that the first button has rounded left edges, the center buttons are squared up, and the last button has rounded right edges. In the image above by Bady, you can see the segmented button bar in the toolbar area of the application.
(more…)

MoneyField

MoneyField

I started writing an article about how to write new UI controls for OpenJFX using all the internal APIs and architecture and so forth. But then I discovered that the control I was writing as a proof of concept was not using any private API at all, and actually was implementing the Skin differently than I had imagined previously, and I thought I ought to blog about it. Behold, the MoneyField!

(more…)

Restricting Input on a TextField

I had some little sample I wanted to write where I had a TextField that restricted input. Maybe somebody else out there has already figured out how to do this elegantly, but I hadn’t and thought it would be worth a small post to demonstrate the technique.

Within the TextInputControl is a Content, which actually models the TextInputControl’s content. So for example, this is where we strip out newlines and such if you paste a String into a TextField that contains such characters, but in TextArea we allow those sorts of modifications. There is a protected getContent() method, so in theory a subclass of TextInputControl can manipulate the content directly, although in the case of TextField, it does not.

In fact, the only places in all the code that actually modify the TextField’s text is in the replaceText and replaceSelection methods defined on TextInputControl. So all you have to do is subclass TextField and override these two methods.

field = new TextField() {
    @Override public void replaceText(int start, int end, String text) {
        // If the replaced text would end up being invalid, then simply
        // ignore this call!
        if (!text.matches("[a-z]")) {
            super.replaceText(start, end, text);
        }
    }

    @Override public void replaceSelection(String text) {
        if (!text.matches("[a-z]")) {
            super.replaceSelection(text);
        }
    }
};

In the future we may want to add a more specific method (maybe called “accept” which takes the proposed new string after the modification) so that in the off chance that TextField or TextInputControl ends up modifying the content from some additional methods beyond these two, you could still have a reliable way to reject invalid input. However for the time being, this should work just fine!