문제

I have recently shifted from c# to try Javafx2. I am also new to this forum. I have been stuck trying to implement internal frames in Javafx. I stumbled upon this link: Internal Frames in JavaFX I have managed to add jfxtras 8 jar file to my project as well as in scene builder 2. However, am stuck in aligning the controls on the window.

This is the fxml file code:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import jfxtras.labs.scene.control.window.*?>

<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="500.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="trials.MamaCont">
<children><Window fx:id="wini" layoutX="122.0" layoutY="105.0" prefHeight="190.0" prefWidth="313.0" title="Window" />
</children></AnchorPane>

and this is the controller class code:

package trials;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.MinimizeIcon;
import jfxtras.labs.scene.control.window.Window;

/**
 * FXML Controller class
 *
 * @author smoothie
 */
public class MamaCont implements Initializable {

    /**
     * Initializes the controller class.
     */


    /*@FXML
    private Button pb;

    @FXML
    private Label lb;*/

    @FXML
    private Window wini;

    /*@FXML
    void pressed(ActionEvent event) {
         lb.setText("Gotcha!!!....");
    }*/

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
        wini.getLeftIcons().add(new CloseIcon(wini));
        wini.getRightIcons().add(new MinimizeIcon(wini));
        //wini.setVisible(false);

        Button butt = new Button("Enter");
        /*butt.setLayoutX(100);
        butt.setLayoutY(100);*/

        Label lab = new Label();
        /*lab.setLayoutX(261);
        lab.setLayoutY(192);*/



        butt.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent t) {
                lab.setText("I've been pressed!!!");
            }
        });

        wini.getContentPane().getChildren().add(butt);
        wini.getContentPane().getChildren().add(lab);
    }    

}

Now, does anyone know how I can be able to align the label so that its text appears below the button? When one clicks on the button the text from the label appears over the button instead of below it.

Has anyone been able to implement internal frames with javafx2 and could you please share how you have managed to put well arranged controls within the internal frames?

Lastly, does anyone know how to make a scene builder control a child of a custom control in scene builder?

I managed to add jfxtras controls to scene builder but unfortunately am not able to add javafx controls to the jfxtras window. In this case, I tried to add a javafx button to the jfxtras window via scene builder but it never worked because it was added to the anchor pane instead of the window resulting to the both the jfxtras window and javafx button being children of the anchor pane.

도움이 되었습니까?

해결책

I managed to solve the issue after toying with the code for some time. What I did was to create the GUI using Scene Builder and linking it with the Java code using a controller. Below are the fxml files:

tingiGUI.fxml

<?xml version="1.0" encoding="UTF-8"?>

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

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="202.0" prefWidth="325.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TingiCont">
<children><Button fx:id="si" layoutX="137.0" layoutY="112.0" mnemonicParsing="false" onAction="#Onyesha" text="Show" /><Label fx:id="lbi" layoutX="100.0" layoutY="70.0" prefHeight="17.0" prefWidth="124.0" />
</children></Pane>

tinGUI.fxml

<?xml version="1.0" encoding="UTF-8"?>

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

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="325.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TinCont">
<children><Button fx:id="bb" layoutX="137.0" layoutY="88.0" mnemonicParsing="false" onAction="#Boom" text="BOOM" /><Label fx:id="lbx" layoutX="84.0" layoutY="147.0" prefHeight="17.0" prefWidth="157.0" />
</children></Pane>

tingGUI.fxml

<?xml version="1.0" encoding="UTF-8"?>

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

<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="219.0" prefWidth="323.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ting.TingCont">
<children><Button fx:id="cmb" layoutX="127.0" layoutY="126.0" mnemonicParsing="false" onAction="#clicked" text="Click me..." /><Label fx:id="lb" layoutX="93.0" layoutY="80.0" prefHeight="17.0" prefWidth="121.0" />
</children></AnchorPane>

Below are the controllers. They extend the Main java class.

TinCont.java

package ting;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;

public class TinCont extends Main implements Initializable{

    @FXML
    private Button bb;

    @FXML
    private Label lbx;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }


    @FXML
    void Boom(ActionEvent event) throws IOException {
        lbx.setText("KAMIKAZE!!!!!!");


        Pane coco = FXMLLoader.load(getClass().getResource("tingiGUI.fxml"));

        Window x = new Window("TINGI WINDOW");

        // set the window position to 10,10 (coordinates inside canvas)
        x.setLayoutX(10);
        x.setLayoutY(10);

        // define the initial window size
        x.setPrefSize(330, 210);
        x.setResizableWindow(false);

        // either to the left
        x.getRightIcons().add(new CloseIcon(x));

        // add some content
        x.getContentPane().getChildren().add(coco);
        anchor.getChildren().add(x);
    }
}

TingiCont.java

package ting;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.event.ActionEvent;

/**
 * Created by Udeman on 2/1/14.
 */
public class TingiCont {

    @FXML
    private Label lbi;

    @FXML
    private Button si;

    @FXML
    void Onyesha(ActionEvent event) {

        lbi.setText("You made it...");
    }

}

TingCont.java

package ting;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;

public class TingCont extends Main implements Initializable{

    @FXML
    private Label lb;

    @FXML
    private Button cmb;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }

    @FXML
    void clicked(ActionEvent event) throws IOException {


        lb.setText("I've been clicked...");

        Pane balou = FXMLLoader.load(getClass().getResource("tinGUI.fxml"));
        Window w = new Window("TIN WINDOW");

        // set the window position to 10,10 (coordinates inside canvas)
        w.setLayoutX(10);
        w.setLayoutY(10);

        // define the initial window size
        w.setPrefSize(330, 210);
        //w.setResizableWindow(false);

        // either to the left
        w.getRightIcons().add(new CloseIcon(w));

        // add some content
        w.getContentPane().getChildren().add(balou);
        anchor.getChildren().add(w);

        //((Node)(event.getSource())).getScene().getWindow().hide();

    }
}

And this is the Main Class. Main.java

package ting;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import jfxtras.labs.scene.control.window.CloseIcon;
import jfxtras.labs.scene.control.window.Window;


public class Main extends Application {

    public static AnchorPane anchor = new AnchorPane();

    @Override
    public void start(Stage primaryStage) throws Exception{

        Pane sunda = FXMLLoader.load(getClass().getResource("tingGUI.fxml"));
        sunda.setLayoutX(130);
        sunda.setLayoutY(60);
        anchor.getChildren().add(sunda);

        primaryStage.setTitle("TING");
        primaryStage.setScene(new Scene(anchor, 600, 400));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

To be able to properly align elements it is best to use the Scene builder. Since I was planning on using internal frames I downloaded JFXtras 8 labs jar file from the JFxtras team. JavaFx8 does not currently support internal frames.

In the Main java class, I created a static anchorpane which the other controllers could inherit because they extend the Main class. From there, I created a JFXtras window and loaded the contents of my fxml file using an fxml loader on a pane. I added the pane to the Jfxtras window and lastly added the window to the anchorpane which was created from the Main class.

In summary, to properly align GUI elements one is best of using scene builder. In order to share the same anchorpane its best to create a static anchorpane in one class and the rest of the controllers to inherit from that class.

It is now possible to add custom UI elements to the current Scene Builder but one is limited on how to use them from the scene builder. You cannot only drag and drop the custom controls but not modify them from Scene Builder

A quick remark, jfxtras window is currently the closest way to have internal frames in JavaFx8. Oracle have not implemented internal frames in Javafx8. However, jfxtras windows for one reason or the other blow out of proportion GUI elements from the fxml file. Well, am going to take a break from coding with Javafx8 until internal frames are introduced. I heavily rely on them. Am returning to c# for now....

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top