Sunday, April 26, 2015

Earth, Moon and Sun using JavaFX 3D

If you're impatient, download the Netbeans project.

Well, I finally was able to get some "Me-time" last weekend and I immediately wanted to try out all those things that I would think of when I'm really busy in office developing boring enterprise stuff. Out of many things I wanted to do, I really wanted to try out JavaFX 3D first. Now, this is because several times in past I've tried to start with JavaFX 3D and always Platform.isSupported(ConditionalFeature.SCENE3D) would return false on my 5 year old Dell laptop with GMA HD Graphics chipset, running Ubuntu. But after recent update to Java 8 Update 40, this changed and the statement started returning true. So I thought I'd give it a try. I'm a complete noob when it comes to 3D. So I had to go through some documentation and articles on developing 3D content specifically using JavaFX. And I thought I'll try to create a simple sun, earth and moon animation as it seemed to cover all the new stuff I've learned.


Only when I was half way through, I realized that I didn't know how to make the sun a real source of light. If you check out the video above you'd see that instead of Sun emanating the light out, the light is actually shone upon it making it look like another huge planet. This is because I've used a PointLight as the light source and I've put it approximately mid-way between Sun and Earth. JavaFX provides only 2 types of light sources: PointLight and AmbientLight. PointLight fit the bill for what I was trying to acheive (due to its directional nature within the scene). Any suggestions on how to make the sun actually look like a Sun are welcome.

I also noticed that the shadow of Moon or Earth doesn't fall on each other whenever there is a Solar or Lunar eclipse situations. 

Other than the Sun and shadows, I'm happy with the way Earth, Moon and the camera rotation turned out to be. The moon is phase locked with Earth (I'm not sure if it can been seen in the video).  The camera rotation works 180 degrees and the performance is quite good. Download the Netbeans project (link at top) if you're interested.

Tuesday, February 11, 2014

Image Slider using JavaFX

A Javascript like Image Slider using JavaFX. I don't think there is much to explain here. The key is to set the clip for the slider. Without the clip, you would just see all the images. Just played some transitions in a constant interval. Check out the code below.



The images in the video are downloaded from Internet and are not mine.

 

Thursday, January 30, 2014

Open Dolphin and Java FX

I came across the Open Dolphin library in one of the Java One presentations. It was really amazing how people at Canoo were able to put things together that we already know and were able build a great library out of it. The first thought that came to my mind after watching the video was, how this can change the way we develop Enterprise Applications, especially the Rich Client ones.

I was recently involved in developing a Rich Client for one of our clients in Switzerland. We used Swing, JDAF and Spring for the client. The development was very rapid and whenever a less experienced developer made some errors like not following the threading model or skipped the JDAF's way of doing things, there would be a lot of mess and we had to clean it up. We did not have a magic tool that would take care of the threading or that would take care of the remoting, while developers can concentrate on the business logic. I wish we had Open Dolphin when we started the project in 2011.

Open Dolphin uses the concept of Shared Presentation Model to keep data between the client and server synced. And with help of binding, the views always reflect whats in the presentation model. So you now have the power to control the view components from the server. All you have to do is change the value in presentation model to which the view component was bounded to. This may sound simple enough, but gives you a great level of seperation, better testing and whole new way of developing Client-Server applications. There are even more to what Open Dolphin can do. Check out the demos section to know them all.



Most of the demos or the examples available on the internet use GroovyFX for client and Grails for the server side. There are some demos available in Java, but they may not be simple enough to understand just the basic setup. So I created a Chat Demo that uses JavaFX for client and Java Servlet based server implementation of Open Dolphin. The purpose of the demo is to show just the bare minimum setup of Open Dolphin in Client and Server. I have always been a fan of Dolphin's long polling. So I decided to write this Chat application using that.

Source Code for demo: https://github.com/raghsr/Chatter

Sunday, November 17, 2013

How to implement Filter/Search for TableView in JavaFX

Filter or Search fields for tables are nothing new. Most of us would have used a custom filter field for JTable in Swing. In this post I'm going to show you how to implement a basic filter for TableView in JavaFX. You can download the source of the example from here.


This filter field will look for each cell in a row and if it finds a match in any of the row, then it retains the row in the TableView else removes it. I have used a TextField as the Filter component (actually, I have used TextFields.createSearchField() from the ControlsFX project. But a simple TextField will work). The filtering logic goes inside the invalidation listener, that is added to the text property of the TextField. I think this is a more cleaner way of implementing the logic, as opposed to implementing the logic in the Key listener (as we do in Swing). Below is the snippet on the filtering logic.

 
  1. private void initFilter() {
  2. txtField = TextFields.createSearchField();
  3. txtField.setPromptText("Filter");
  4. txtField.textProperty().addListener(new InvalidationListener() {
  5. @Override
  6. public void invalidated(Observable o) {
  7. if(txtField.textProperty().get().isEmpty()) {
  8. table.setItems(data);
  9. return;
  10. }
  11. ObservableList<Employee> tableItems = FXCollections.observableArrayList();
  12. ObservableList<TableColumn<Employee, ?>> cols = table.getColumns();
  13. for(int i=0; i<data.size(); i++) {
  14. for(int j=0; j<cols.size(); j++) {
  15. TableColumn col = cols.get(j);
  16. String cellValue = col.getCellData(data.get(i)).toString();
  17. cellValue = cellValue.toLowerCase();
  18. if(cellValue.contains(txtField.textProperty().get().toLowerCase())) {
  19. tableItems.add(data.get(i));
  20. break;
  21. }
  22. }
  23. }
  24. table.setItems(tableItems);
  25. }
  26. });
  27. }
Every time the text property of the TextField is invalidated, the listener will check for matching items in the table content and set the table with items that only match the filter criteria. In the above snippet, the variable data holds the original list of items for the table. In Swing context you can think of it like a original table model. So when you filter, a new list is created to hold only the matching rows and this list is set as items to the TableView. 

The whole example is available as a maven project. Download to explore more. This is a very basic implementation. Some of the limitations of this filter is that it calls toString() to compare the contents. That would need some clean up. More features like filtering based on column index, highlighting the matching text in the table, showing some animation in case of really big list of data etc.. can be added to make this a perfect JavaFX control. 

Happy coding!!  

Table Filter Demo Example : https://drive.google.com/file/d/0B96EBDPI6nZZX2VpdThBa3RnOGc/view?usp=sharing

Wednesday, July 24, 2013

Animated Wizard using JavaFX

I recently got to work on a Wizard Type application for one of my clients. Also I am currently playing with the JavaFX Animations. Animations were never straight forward in Swing and even if we were to develop a custom animation, performance was a big factor to consider. This made JavaFX animations a lot of fun.

In this post I'm going to share a simple wizard like application, that has two forms. Not a real world use case, but could give you some basics on how animations can be used in a wizard.

The code for this application can be downloaded as a Netbeans project from here.

I use a single Parent View and two Child Views in this demo. The Parent view has Stack Pane in place, which acts as a host for the child views. The child view is swapped when "Next" button is clicked.



The nodes are animated in the initialize method of the controller class for each view. For this purpose I have a AnimationManager, which will animate the nodes for me. The layout of each child view (the actual forms), is simple. I have got a VBox and number of HBox s' inside it, for each field.


If you are a WPF developer trying to understand JavaFX, VBox is similar to a WPF StackPane with vertical orientation and HBox is similar to a WPF StackPane with horizontal orientation. 

The AnimationManager helps me animate all the 1st level child of the VBox (which are HBoxs). Below is the method from AnimationManager that animates the nodes.

  1. private static ObservableList<Timeline> getTimelines(Parent node) {
  2. double deltaSeconds = 0;
  3. ObservableList<Timeline> timeLines = FXCollections.observableArrayList();
  4. ObservableList<Node> children = node.getChildrenUnmodifiable();
  5. for(Node child: children) {
  6. deltaSeconds += 0.5;
  7. Rotate rotate = new Rotate(-90, 0, 0, 0, Rotate.Y_AXIS);
  8. child.getTransforms().add(rotate);
  9. Timeline anim = new Timeline(
  10. new KeyFrame(Duration.seconds(deltaSeconds),
  11. new KeyValue(child.opacityProperty(), 0),
  12. new KeyValue(rotate.angleProperty(), -90)),
  13. new KeyFrame(Duration.seconds(deltaSeconds + 1.0),
  14. new KeyValue(child.opacityProperty(), 100),
  15. new KeyValue(rotate.angleProperty(), 0))
  16. );
  17. timeLines.add(anim);
  18. }
  19. return timeLines;
  20. }

This method returns a List of Timeline objects to the caller. The AnimationManager is called inside the initialize method of the controller. And hence when the views are initialized the animation is played. Download the source to experiment further.