Tag Archives: JavaFX

JavaFX: Instantiate Application within Spring Context

JavaFX application is typically instantiated via calling static method launch(…) on object inherited from Application:

import javafx.application.Application;

public class TestApp extends Application {
	public static void main(String[] args) {
		launch(args);
	}
}

But this hardly fits into IoC solution – in this case Spring Context. I was trying to find suitable solutions but failed. There is no simple way how to instantiate Application in dynamic way.

But there is workaround: Start application in static way, in start(…) method save created Application instance into static variable and then create Spring context. Instance of Application is accessible through static method.

So something like:

import org.apache.commons.lang3.Validate;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class TestApp extends Application {
	private static volatile TestApp singleton;
	
	public static void main(String[] args) {
		launch(args);
	}

	public static TestApp getSingleton() {
		Validate.notNull(singleton, "Not yet created instance of %s!", TestApp.class.getName());
		return singleton;
	}

	@Override
	public void start(Stage primaryStage) throws Exception {
		Validate.validState(singleton==null, "Only one instance of %s may be created!", getClass().getName());
		
		singleton = this;
		
		try (ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/beans.xml")) {
			// Context initialized!!!
		}
	}
}

With following in beans.xml:

<bean id="app" class="test.TestApp" factory-method="getSingleton"/>

Then “app” behaves as plain bean and you can use it as such.

JavaFX: Dynamic context menu on TreeView

I did not find any simple approach so I had to invent own :-]

package test;

import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;

//custom implementation of TreeView - but same principle should 
//work on instance of TreeView without inheritance
public class ObjectsTree extends TreeView&lt;MyNode&gt;{

  //custom context menu that can create proper item for selected item
  //again, custom class is not necessary you can do it on
  //instance of ContextMenu
  private DynamicContextMenu menu = new DynamicContextMenu();

  public ObjectsTree() {
    ...
    addEventHandler(MouseEvent.MOUSE_RELEASED, e-&gt;{
      if (e.getButton()==MouseButton.SECONDARY) {
        TreeItem&lt;MyNode&gt; selected = getSelectionModel().getSelectedItem();
				
				//item is selected - this prevents fail when clicking on empty space
				if (selected!=null) {
				  //open context menu on current screen position
					openContextMenu(selected, e.getScreenX(), e.getScreenY());
				}
      } else {
        //any other click cause hiding menu
        menu.hide();
      }
    });
    ...
  }

  private void openContextMenu(TreeItem&lt;ObjectsTreeNode&gt; item, 
    double x, double y) {
    //custom method that update menu items
    menu.setContext(item.getValue());
    
    //show menu
    menu.show(this, x, y);
  } 
}