JavaFX layout, a silver lining?

  • Post category:JavajavafxUI

As described in the previous post, I believe that JavaFX’s layout mechanism is not as good as it could (should) have been. Naturally it is one thing to complain, another to offer improvement suggestions, but the best is to provide alternatives. First there is MigPane, which is a very powerful layout manager, but it is also possible to ‘slap’ on a different API onto existing layout managers. And that is what is being attempted in the JFXtra’s drop-in replacement layout managers. These layout managers extend the existing one, but add a different style.

The basic idea is that instead of writing:

VBox lVBox = new VBox(5.0);
Button b1 = new Button("short");
lVBox.getChildren().add(b1);
VBox.setVgrow(b1, Priority.ALWAYS);

You can write:

VBox lVBox = new VBox(5.0);
lVBox.add(new Button("short"), new VBox.C().vgrow(Priority.ALWAYS));

(more…)

Continue ReadingJavaFX layout, a silver lining?

It’s not all gold and sunshine; JavaFX layout

  • Post category:JavajavafxUI

After my previous post, praising the properties and binding mechanism, I’d also like to voice an opinion on something on which I think the JavaFX team has dropped the ball.

In the previous post about Agenda control I explained that there were two ways I updated the nodes in Agenda; either I setup binding in the constructor, or I listen to relevant properties and call a relayout() method, setting the appropriate values there. Especially the binding is a powerful feature. No software engineer can deny that the sniplets below don’t have a certain beauty to them.

Adding a rectangle that serves as a dragger at the bottom of an appointment:


durationDragger.xProperty().bind(widthProperty().multiply(0.25)); // 25% offset from the left border
durationDragger.widthProperty().bind(widthProperty().multiply(0.5)); // 50% of the width of the appointment
durationDragger.yProperty().bind(heightProperty().subtract(5)); // 5 pixels from the bottom border
durationDragger.setHeight(3); // 3 pixels high

Making sure the day head and day body line up:


header.getChildren().add(dayHeader);
week.getChrildren().add(dayBody);
dayHeader.xProperty().bind( dayBody.xProperty());
dayHeader.widthProperty().bind( dayBody.widthProperty());

What is important here is that the x,y,w,h values are set directly on the children. The container does not do any layout, it simply draws its childeren where they say they want to be. This is called an ‘absolute’ layout. All other layouts (VBox, HBox, BorderPane, …) do not want you to set the x,y,w,h of the children, their added value is that they’ll calculate and set them for you. (more…)

Continue ReadingIt’s not all gold and sunshine; JavaFX layout

Writing Google Calendar in JavaFX

  • Post category:JavajavafxUI

After getting my feet wet writing the ListPicker and CalendarPicker control in JavaFX for the JFXtras project, I felt it was time to put my aim at something bigger; I always wanted to write a control that does a “Google Calendar”. Even though such a control on the surface seems simple, there are many things that make it a real challenge and fun for a software engineer to create. For example the beauty of how overlapping appointments are rendered. So after a few days where the spare time went into drawings and scribbles on paper, fleshing out how things should be set it up, the coding started. There were a few things I would like to do different from Google’s version.

  1. When I plan an appointment, I always forget to look at the whole day events, and often get conflicts because of that. So I wanted a whole day event to have a presence during the whole day.
  2. Google only allows for appointments that span a certain amount time. Tasks (which basically only have a single date & time) are not supported. Google has a task feature, but it is not mature enough IMHO in terms of reminders and visibility.

So before diving into how the control is set up, first a quick peek at the state of affairs when writing this blog (tasks are not implemented yet):

(more…)

Continue ReadingWriting Google Calendar in JavaFX

Stand alone business model with Activiti, Eclipselink and unit tests on PostgreSQL

Somewhere around 2007 – 2008 I was setting up a new project which had a business model (BM) as the central component. The business model I envisioned had a three layered structure: an AbstractBean handling all the Java bean plumbing, a from-the-database-reverse-engineered class with the properties (setters and getters), and finally a class containing the custom code on top. I wanted to settle on a standard (JPA) and tried using Hibernate at first, but it could not support this layered structure back then, so I ended up using Eclipselink (and with great satisfaction ever since, I must add).

I also have never been a fan of pure application servers (EJBs), so this BM is compiled into a single jar (already postprocessed by Eclipselink), and simply included in all kinds of applications; a client-server Swing application, a REST interface to support an Android app, several im- and exporters for EDIFACT, emails, XML, and of course a nice in-house webapp. Not having an additional single point of failure (besides the database) is very pleasing and keeps the overall architecture much more simple. (more…)

Continue ReadingStand alone business model with Activiti, Eclipselink and unit tests on PostgreSQL

JavaFX 2.0 bubblemark – part 2

  • Post category:JavajavafxUI

The first post on the JavaFX 2.0 bubblemark created some feedback, most notably an email from the JavaFX engineering team stating in so many words that JavaFX 2.0 has an issue and that is why it per default is not running on full speed. But the remedy should be the magical “-Djavafx.animation.fullspeed=true” option. So without further due the JavaFX bitmap test was run with that option.

So first here is the total view for all 4 tests (the ‘+’ is the fullspeed option):

And the zoomed-in version:

(more…)

Continue ReadingJavaFX 2.0 bubblemark – part 2

JavaFX 2.0 bubblemark

  • Post category:JavajavafxUI

Oracle has released the revamped JavaFX 2.0 on JavaOne 2011. It’s an interesting step which immediately invokes many questions. What is the target audience for JavaFX? Which technology segment does it aim at? What are the chances it will actually claim a piece of that segment? Is it any good at the segment it is aiming at? Only the future will tell the answers to all the questions. But some can be attempted to be answered today.

First of all a short summary of what I believe JavaFX 2.0 is: JavaFX attempts to be a higher performance graphics framework, with a UI layer on top, able to display different types of media.

  • “Higher” means that it is not aiming at high end gaming (for example the recently released Battlefield 3 and Call of Duty Modern Warfare 3), but more at the level of platform games like Mario Bros or the fancier and animated user interfaces that some applications have lately.
  • “Graphics framework” indicates that it is not a UI library in its core (like Swing or SWT), but its designed primarily for drawing, manipulating and animating shapes like circles, rectangles and lines.
  • “UI layer on top” to note that it does come with a good set of UI controls, that are drawn using the graphics framework and thus can easily be made “fancy”.
  • “able to display different types of media” means that there is support for playing audio or video streams.

This kind of framework is commonly known as a RIA, or rich internet application, framework.

Having established the technical intention of JavaFX, the first step would be to see if it is any good at what it’s trying to be. This means bringing out the tame racing driver, aka a common frame of reference. For benchmarking a RIA the unofficial first thing to do is throw the bubblemark test at it. (more…)

Continue ReadingJavaFX 2.0 bubblemark

Oracle vs Google

The latest news about the infringement dance Google and Oracle are doing, indicates that Google may be in serious trouble. These law suites usually are far-from-my-bed things which are taken note of, wondered about, and swapped out for day to day activities. But, for some reason, this morning I woke up early and felt angry. Very angry even. And it was aimed at Oracle.

I’ve coded Java since version 1.1. The last 10+ years of my professional life have been about Java. I’ve spent many of my spare time learning, fine tuning, enhancing my Java skills; I’ve tried to contribute as a compensation for making my work possible; even this week I’ve spent precious family time on JavaFX (JFXtras). I never believed that Java was dead. No language was able to pull me away; no Jython, Scala, Haskell or Groovy, no C# or mono. Oh, I’ve examined them all, but they just confirmed that Java is a good and solid choice for the years to come.

But this morning, for the first time, I wondered that if Oracle would use Java to really hurt Google (considering the amount of money they’re suing for, that is a real possible scenario). If Oracle would abuse their stewardship of Java to really hurt one of the biggest contributors to the Java ecosystem. If this law suite turns out to be more than just a slap on the wrist to make clear who’s boss. If Oracle loses the benefit of the doubt, if I then still would be willing to invest my private time in a community with such a leader. With such risk of innovation being slammed down by legislation… Oracle may be able to accomplish what nothing could before; kill my Java community spirit. (more…)

Continue ReadingOracle vs Google

JavaFX 2.0, Swing 2.0?

At the beginning of my previous post I mentioned that I was stuck in the implementation of the calendar picker, because I was using one listener for 42 ToggleButtons, and I could not find out which of the 42 ToggleButtons was actually clicked. The code I have looks like this:

class Skin
{
	/**
	 * create the skin by using other controls
	 */
	private void createNodes()
	{
		for (int i = 0; i < 6 * 7; i++)
		{
			ToggleButton lToggleButton = new ToggleButton();
			lToggleButton.selectedProperty().addListener( iSelectedListener );
			...
		}
	}

	// one listener for all 42 buttons
	final private InvalidationListener<Boolean> iSelectedListener = new InvalidationListener<Boolean>()
	{
		@Override public void invalidated(ObservableValue<? extends Boolean> observableValue)
		{
			// selected or deselected
			boolean lSelected = observableValue.getValue();

			// TODO: which ToggleButton was pressed?
		}
	}
}

After having dropped this at the JavaFX people I went into pause, assuming the InvalidationListener API would be extended to include the origin of the event (like Swing events do). After some time Richard Bair came back to me and explained that extending the API with a reference to the bean would mean additional bytes for each property. My initial reaction was; so??? It’s just a few bytes? But then I realized that JavaFX is not about controls, but about graphics; controls are just a subset in which I’m very interested, but the real focus of JavaFX is much more basic and raw. There will be applications with thousands of nodes, and then a few bytes per property quickly become megabytes and the rise of the mobile devices suddenly make memory important again. So it became clear that extending the InvalidationListener API is not wise indeed. (more…)

Continue ReadingJavaFX 2.0, Swing 2.0?

JavaFX 2.0 EA binding

After Swing, JavaFX 1.x and the iPad, now JavaFX 2.0 is candidate for the calendar picker shake down. Using MigLayout I’ve setup the basic day picking logic, but currently am stuck in build b21, because the events on the selected property in ToggleButton do not tell me which togglebutton was actually pressed, which is quite handy if you have 42 of them on screen. So I decided to focus a bit on binding instead.

My binding experience comes from JGoodies used in connecting Swing components to business model bean properties, usually using JGoodies’ BeanAdapter (which takes away the need to rebind every single property when the business model bean is changed underneath a Swing screen). Since I’m primary focussed on JavaFX’s controls at the moment, I wanted to see if I could bind my calendar picker to a business model. I’m also going to assume future 2.0 in which the properties on the business model also are using JavaFX properties. So I constructed a dummy business model with one property:

	class BusinessModelBean
	{
		final public ObjectProperty iCalendarObjectProperty= new ObjectProperty();
	}

(more…)

Continue ReadingJavaFX 2.0 EA binding

JavaFX 2.0 EA and MigLayout

  • Post category:JavajavafxUI

Oracle rebooted JavaFX and finally positioned it as what I for a long time have been longing for; Swing 2.0. Let’s not kid ourselves; JavaFX is a new UI library for Java, using the API lessons learned from Swing and taking it to the next level with animations and effects. The concept is powerful enough to even go into the 3rd dimension soon. And more importantly; JavaFX2 finally has a good integration (and therefor migration path) with Swing, so it actually has an existing user base which can easily be persuaded to take a peek. Not to mention the fact that it now uses Java instead of JavaFX script, so the EDI support is great right from the start. (Well done Oracle!) But if this doesn’t sound like Swing 2.0, I don’t know what will.

So what is JavaFX2 like? Well… I like it. The API is clean and intuitive. Since it uses a different approach, making everything from simple lines to complete tables just a node in a tree, it means that I still have to really get my head around that. Fact remains that this approach allows to easily add effects and animation on anything, being it on a square or complete screen (they’re all just nodes after all). But I know I will initially use JavaFX in existing Swing applications, so my primary interest is in the controls. In order to make my life easier, I decided that porting MigLayout could be a good idea.

I must say that the initial results in my opinion are not bad at all. Below is an example of a simple test involving a TextBox and Rectangle:

public class MigPaneTest1 extends Application {

    public static void main(String[] args) {
        Launcher.launch(MigPane.class, args);
    }

	@Override
	public void start(Stage stage) {

        // root
        MigPane lRoot = new MigPane(new LC(), new AC(), new AC());

        // add nodes
        lRoot.add(new TextBox(10), new CC());
        lRoot.add(new Rectangle(30,30, Color.YELLOW), new CC());

        // create scene
        Scene scene = new Scene(lRoot, 600, 300);

        // create stage
        stage.setTitle("Test");
        stage.setScene(scene);
        stage.setVisible(true);
    }
}

This results in the following layout:

(more…)

Continue ReadingJavaFX 2.0 EA and MigLayout