This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information

How to read an fxml file inside a UIInternalFrame?

General questions regarding the development with JavaFX UI for JVx.

Re: How to read an fxml file inside a UIInternalFrame?

Postby Support@SIB » Fri Oct 06, 2017 5:47 pm

JVx' UI is an UI abstraction but it doesn't hide the underlying technology. You could add the root node as new UICustomContainer(root).

An UICustomContainer or an UIComponent wraps the given technology dependent resource. An example with Swing is here
User avatar
Support@SIB
 
Posts: 353
Joined: Mon Sep 28, 2009 1:56 pm

Re: How to read an fxml file inside a UIInternalFrame?

Postby Support@SIB » Fri Oct 06, 2017 5:50 pm

It's always possible to directly access the technology dependent resource, e.g. frame.getResource() and cast it to e.g. FXInternalWindow.

But be careful, if you use the underlying technology directly, it's not easy to use another UI technology without problems!
User avatar
Support@SIB
 
Posts: 353
Joined: Mon Sep 28, 2009 1:56 pm

Re: How to read an fxml file inside a UIInternalFrame?

Postby rzenz » Mon Oct 09, 2017 10:05 am

Just to be clear, what you're looking for is the UICustomComponent, which allows to wrap native components into the UI layer. See the blog post about creating custom components, to be exact the section "Wrapping custom components with UICustomComponent" will interest you.

So what you actually want to do is this:

Code: Select all
    AnchorPane root = FXMLLoader.load(resource);
    UICustomComponent wrappedRoot = new UICustomComponent(root);
    interalFrame.add(wrappedRoot, UIBorderLayout.CENTER);


Also if you are a beginner with JVx, I'd suggest to read through the whole JVx Reference series on the blog, or at least the post about how the UI layer works and also have a look at the JVx FirstApp.
User avatar
rzenz
 
Posts: 36
Joined: Mon Dec 12, 2016 1:40 pm
Location: Vienna, Austria

Re: How to read an fxml file inside a UIInternalFrame?

Postby rzenz » Wed Oct 18, 2017 11:00 am

How to close the (internal) frame is easy enough, simply set its visibility to false, or call dispose.

How to get it do that from inside a JavaFX component on the other hand, is a little bit more involved. Either you create a controller class which handles the button event, or you wire the event up manually.

You could set a controller, for example by using the current class which you are in. Assume the following FXML file:

Code: Select all
<?xml version="1.0" encoding="UTF-8"?>

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

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <center>
        <Button id="button" mnemonicParsing="false" text="Button" onAction="#handleButtonAction"/>
    </center>
</BorderPane>


And this code in the JVx project:

Code: Select all
public class FileLoadedFrame extends UIFrame
{
    public FileLoadedFrame()
    {
        super();
       
        setLayout(new UIBorderLayout());
        add(loadContent(), UIBorderLayout.CENTER);
    }
   
    @FXML
    protected void handleButtonAction(ActionEvent pActionEvent)
    {
        System.out.println("Button pressed.");
    }
   
    protected IComponent loadContent()
    {
        FXMLLoader loader = new FXMLLoader(FileLoadedFrame.class.getResource("test.fxml"));
        // Set this instance as controller before loading the actual document
        // so that the specified method can be executed on button press.
        loader.setController(this);
       
        try
        {
            loader.load();
        }
        catch (Exception e)
        {
            // TODO Handle the exception.
            e.printStackTrace();
           
            return null;
        }
       
        // We need to assign it here once to make sure that it has the correct
        // type. UICustomComponent does have two constructors, one with
        // IComponent and Object, to avoid undefined behavior we have to be
        // explicit about the type of the parameter. That is needed because
        // getRoot() returns the type that is expected, which would be undefined
        // behavior if we hand it directly to the constructor.
        BorderPane root = loader.getRoot();
       
        return new UICustomComponent(root);
    }
   
}


By setting the class as controller, the button is able to call the handleButtonAction method.

The second way is to manually wire the event against the button, if we assume a nearly identical FXML file from above, just without the onAction property:

Code: Select all
<?xml version="1.0" encoding="UTF-8"?>

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

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <center>
        <Button id="button" mnemonicParsing="false" text="Button"/>
    </center>
</BorderPane>


We can lookup the button and manually set its action event:

Code: Select all
BorderPane root = FXMLLoader.load(this.getClass().getResource("test.fxml")
Button button = ((Button)root.lookup("#button"));
button.setOnAction(this::handleButtonAction);


Which can become quite tedious when having a lot of events, though.
User avatar
rzenz
 
Posts: 36
Joined: Mon Dec 12, 2016 1:40 pm
Location: Vienna, Austria


Return to Development