Skip to main content

UI Controls in JavaFX 1.2

Posted by malenkov on June 2, 2009 at 11:23 PM PDT

So the next version of JavaFX has been released. I developed an example that shows all the node-based UI controls that had been added to the API to replace the controls based on the Swing library. Note, that new UI controls are available on all platforms including mobile.

The following set of the controls is included in the current API:
TextBox: A control which displays and accepts input of text.
Button: A simple command button control.
ToggleButton: A control that possesses the ability to be selected.
RadioButton: A kind of a toggle button that has another appearance.
CheckBox: A tri-state selection control with a tick mark when checked.
Hyperlink: An HTML like text label that responds to rollovers and clicks.
Slider: A control that enables selecting a value by sliding a knob.
ProgressBar: A component used to show the progress of a task.
ProgressIndicator: A component that displays the progress in a form of a pie chart.
ListView: A simple list of items that can be editable.
ScrollBar: An element that enables the graphical content of a container to be scrolled.

You can learn more about these controls in the Powerful UI Capabilities With Node-Based Controls tutorial. This article discusses some performance aspects of the UI controls implementation and suggests how to employ them in your applications. First, run this example.

ScrollPane and performance

As you may see, the main window does not contain a scroll bar. However, you can see it in action in the ScrollPane class that supports a mouse wheel. The values of the boundsInParent variable defined in the Node class should be used in expressions to lay out the content. Never bind these values directly! The rational is that these values are updated many times per second and regular recalculations of expressions substantially decrease performance of your application. In order to resolve this problem, I created the Bounds class. The coordinates and dimensions are updated only when the corresponding values actually changed. If you compile and run the application by using the Bounds class, you will see that the values with the prefix content are constantly updated, even if the values are not changed. Another recommendation is to remove println, because the debug printing decreases performance as well.

ScalePane

Games often require to show all the graphical content constantly. That's why, I developed the ScalePane class for these purposes. It is constructed similar to the ScrollPane class and preserves the aspect ratio. Try this example to explore it in action. In some rare cases you might want to disable preserving the aspect ratio, however, run this example to ensure that is looks ugly.

Application

Having reviewed a lot of samples, I realized that each model of the application deployment requires specific actions. All the possible actions are implemented in the Application class. The application not only looks and works identically on the mobile device and in the full-screen mode, but additionally, it enables dragging the applet from a browser without pressing the Alt key. The main class of the example is very simple now.

Application {
  title: "JavaFX Controls"
  header: ImageView { ... }
  background: LinearGradient { ... }
  content: ScrollPane {
    background: Color.WHITE
    border: 10
    content: ...
  }
}

Refer to the source code of the Controls class for more infromation.

Related Topics >>

Comments

Hello Sergey, First, I want

Hello Sergey, First, I want to thank you for sharing your work! I'd like to use your ScrollPane implementation in my project, but there is an issue with it. Maybe you can help me to resolve it. In your example code you bind the sizes of the ScrollPane to the sizes of the Scene. This works perfectly in situations when the ScrollPane must take the whole area of the scene or when the area given to the other components has a fixed size. But what if we need a flexible layout? I would like to be able to say that the ScrollPane should take the whole amount of the available space (like "growing" cells in GridBagLayout) except for the necessary space which is given to the other components, so that the size of the ScrollPane is calculated automatically without the need to manually subtract the sizes of the components in the bind expression (like in the commented code below). Is there a way to achieve this? Thanks in advance.

var button:Button;
def stage:Stage = Stage {
scene: Scene {
width: 800
height: 600
content: [
VBox {
content: [
button = Button {
text: "My Button"
}
ScrollPane {
width: bind stage.scene.width
height: bind stage.scene.height // - button.height
node: Group {
content: [
for (i in [0..20], j in [0..20]) {
Rectangle {
fill: Color.GRAY, stroke: Color.DARKGRAY
width: 50, height: 50
x: 50 * j, y: 50 * i
}
}
]
}
}
]
}
]
}
}

Hi Ilya

A custom node should not lay out itself, because it can be added into any container. You should set a layoutInfo variable, that will be used by a container to layout your node. Please, read the article written by Amy.

Hi Sergey

Thanks for controls shared. Your ScrollPane is very interesting.
Can I add it to a simple Rectangle node because i want make many scrollable composants ?
If it is not possible, Can I manipulate many Application.fx(Stage) object into an principal stage?
thanks at advance, and sorry for my bad english.

Hello

I do not understand what do you want to do with the Rectangle class. It is not a container, so you can't add any node to a rectangle. You can use my ScrollPane with any container such as Group, Tile, and other.

The Application class corresponds to single stage. It was created to simplify application development for different deployment models: desktop, applet, mobile.

It is very easy to create custom table. But I think that Tree is more complex. I hope that this functionality will be added. Stay tuned!

Sergey, this is great news. Could you throw some light on the best practices for controls not covered by JavaFX (e.g. Tree, Table, etc)? Should we write wrapper classes for them in the short term? Also, can we expect JavaFX equivalents in the long term? Thanks.

Just having a small problem with following the ScalePane and ScrollPane examples .... Compiler gives "javafx.geometry.Bounds is abstract; cannot be instantiated" on def bounds = Bounds { content: bind content } Am I missing something stupid here?

@all: I do not develop JavaFX. I just create JavaFX samples for fun.

@pupmonster: technically - possible, but legally - not possible

@goron: JavaFX is based on Java. It is too difficult to create independent language from scratch.

Hiya all, Well, I must say I agree with goron. We have to be competitive on all major consumer operating systems. I would like to make a screenshot -- not possible here -- but I trust you will agree with this point -- two title bars are seriously dorky. I wonder if there really is technologically _nothing_ that can be done by Sun (or the open user community) to create a competitive user experience running JavaFX on OS X when Apple drags its feet? Some downloadable JDK/Jre Fixer or some such thing?

> @pupmonster: The problem is that Java for OS X is supported by Apple. I don't know when it will be good enough. That's not a good attitude. If you want to be relevant in a world of Flex you have to do better, I think.

Created an issue in the JavaFX Jira: RT-4895

Sergey and sunburned, I'm running 64-bit Ubuntu and it JavaFX via webstart (including the Darkchat application) do not work on my system. The JNLP file for the JavaFX runtime, found here: http://dl.javafx.com/1.2/javafx-rt.jnlp only seems to mention "i386" and "x86" architectures for Linux. I don't know what the architecture ID for 64-bit Linux should be ("x86-64"? "x86_64"? "amd64"?), but it does not seem to be there. I hope that can be fixed soon... I also downloaded NetBeans with the JavaFX SDK 1.2, and that runs fine, but one of the example apps with a video player (MediaBox) does not work - I just get a window with the text "We're sorry, this video can't be played now". Do the video codecs work on 64-bit Linux?

Hi Sergey, First, I'll get some more info about the javafx example problem and try to file a bug report. I think the problem may be related to the "Issue: RT-3780 and RT-3842: Cannot launch JNLP application" listed in the release notes. Since it's working on ubuntu (presumably 32-bit), maybe it's a 64-bit only problem with webstart. I downloaded the netbeans javafx sdk (linux) plugins, and the plugin sample fx code DOES run in netbeans, but the html files are broken in the browser. Second, that's great news to here that JWebPane is coming along nicely. Is there anywhere we can get a look at it? Thanks, --sunburned

@pupmonster: The problem is that Java for OS X is supported by Apple. I don't know when it will be good enough.

@sunburned: JavaFX works fine on Ubuntu at least. Could you please file a bug to javafx-jira.kenai.com?

@etf: I meant that all necessary code can be easily created. GUI design will take time, but it can be similar to ListView.

@tdanecito: JWebPane is ready. Almost. JMC supports external codecs installed on a client-side.

Hi Sergey, Thanks for the example app. Looking through it now and learning .... I have run the above on Linux and Windows and it looks good. I wonder if you or the Sun team are aware of problems running under OS X. a.) First OS X adds an extraneous/duplicate title frame header. Is this a programmatic issue I wonder? I sure hope that it is not in the JavaFX platform. b.) In the ListView in OS X when you scroll to the bottom with the down arrow key, i.e. not using the scrollbar and the mouse, the scroll bar disappears when you hit the bottom-most element. This problem does not occur, again, when running Linux or Windows. Regards, Steve

The animations used make the UI feel to respond very slow, for example when clicking the buttons rapidly. Also the textbox resizes depending on whether it has focus or not. If it is intended, the textbox label should resize with it (or the VBox layout needs to support baselines like it was added to the recent Swing layout managers).

Is it just me, or do JavaFX apps tend to freeze for an appreciable amount of time when interacted with for the first time? i.e. when u click to perform something that should trigger an event or a repaint?

What do you mean by "create custom table"? Just for fut it could be easy, but real, production quality table view widget is a big deal. Without such components JavaFX may be used only for playing, not for real work.

The none of the examples here or on the javafx page, or in the javafx1.2 sdk work. In the past, even though I'm using debian linux amd64 with the jdk 1.6.0 u12, javafx examples would run through webstart in iceweasel (aka firefox). Now nothing works. I updated my jdk to u14 (including the link to the libnpjp2.so plugin), all examples are still broken even though applets run fine. I downloaded the linux javafx1.2 sdk and tried the examples there -- none would work. The error I'm getting for the "Controls" example (and all the other examples) is: "Unable to launch the application" Under the details, it says under the "Exception" tab: "Error: Unexpected exception: java.lang.reflect.InvocationTargetException java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.sun.javaws.Launcher.executeApplication(Launcher.java:1302) at com.sun.javaws.Launcher.executeMainClass(Launcher.java:1248) at com.sun.javaws.Launcher.doLaunchApp(Launcher.java:1066) at com.sun.javaws.Launcher.run(Launcher.java:116) at java.lang.Thread.run(Thread.java:619) Caused by: java.lang.NoClassDefFoundError: com/sun/javafx/runtime/Main at com.sun.javafx.runtime.main.Main.main(Main.java:35) ... 9 more Caused by: java.lang.ClassNotFoundException: com.sun.javafx.runtime.Main at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:188) at com.sun.jnlp.JNLPClassLoader.findClass(JNLPClassLoader.java:257) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at java.lang.ClassLoader.loadClass(ClassLoader.java:252) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) ... 10 more" What's going on with JavaFX? I'd like to try it, but it's nothing but frustration.

Yes - I am not using the Bounds class in your post - doh! Missed that highlight and assumed using javafx Bounds - Note to self - read carefully

@carldea: Thanks, Carl. The ListBox bug is known, but the TextBox bug looks strange. I'll check it with the latest version and file the bug.

Hello Sergey, I seem to notice 2 strange behaviors once I click on the maximize button to max window size to screen (middle upper right corner of application). https://malenkov.dev.java.net/20090602/Controls1.jnlp The textbox doesn't seem to allow user to type keystrokes when app is maximized. Also, in the ListBox control when selecting an item (say the 1st item) and you use the arrow key (down) to move to each item to the very end the scroll bar disappears sometimes. -Carl

rich text editor

Do we have rich text editor in javafx??

Not yet as I know

Not yet as I know