如何使用GridPane的fx:id通过controller.java文件向JavaFX gui添加按钮



对于JavaFX来说还是比较新的,我在将按钮添加到我已经设置的GUI中遇到了一点麻烦。

我有3个文件:Main.java, Controller.java和sample。FXML(每个位于下面)

从我通过教程和文档所读到的,controller .java文件被加载并链接到fxml文件,由于"fx:controller"部分-但除此之外,我不能正确地让程序运行该方法。

我试过设置Main.java作为控制器,只是以这种方式融合代码(失败)。甚至主动违反了形式,并试图在Main.java文件中创建Controller.java的新实例(这实际上只是在程序运行时加载的内容旁边创建另一个实例),但也失败了。

指针吗?

Main.java

package soundboardEoZ;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Main extends Application {
    int sound_index = 1;
    int target = 10;
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();

        while (sound_index < target){
            // This is where I want to call the addButton() method from Controller.java
            sound_index++;
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

Controller.java

package soundboardEoZ;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
public class Controller {
    int index = 2;
    int target = 10;
    @FXML
    GridPane button_grid;
    void test(){
        System.out.println("Testing");
    }
    void addButton(){
        Button sound_button = new Button("Button_" + index);
        button_grid.add(sound_button, index,2);
    }
}

和FXML文件

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Text?>
<!--VBox is a single column panel-->
<?import javafx.scene.text.Font?>
<VBox id="vbox" prefHeight="400" prefWidth="1000" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="soundboardEoZ.Controller">
    <MenuBar fx:id="menuBar"> <!--Literally a MenuBar-->
        <menus> <!--Holds the menu concept for the bar-->
            <Menu text="File"> <!--Menu holds Items-->
                <items>
                    <MenuItem text="New" />
                    <MenuItem text="Open" />
                    <SeparatorMenuItem />
                    <MenuItem text="Save Settings" />
                    <SeparatorMenuItem />
                    <MenuItem text="Settings" />
                </items>
            </Menu>
            <Menu text="Edit">
                <items>
                    <MenuItem text="Copy" />
                </items>
            </Menu>
            <Menu text="About">
                <items>
                    <MenuItem text="Team" />
                </items>
            </Menu>
            <Menu text="Help">
                <items>
                    <MenuItem text="Guide" />
                    <MenuItem text="Forums" />
                </items>
            </Menu>
        </menus>
    </MenuBar>
    <Pane>
        <GridPane>
            <Button GridPane.columnIndex="0">I'm another Test</Button>
            <Text fill="RED" stroke="BLACK" strokeWidth="2.0" GridPane.columnIndex="1">
                <font><Font size="25"/></font>
                Testing
            </Text>
        </GridPane>
    </Pane>
    <GridPane fx:id="button_grid" hgap="10" vgap="10" xmlns:fx="http://javafx.com/fxml">
        <!--<Button GridPane.columnIndex="0" GridPane.rowIndex="1">Hello!</Button>-->
        <!--<Button GridPane.columnIndex="1">Hiya!</Button>-->
        <!--<Text text="Clickity!" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2" />-->
        <!--<Label text="Configuration Name:" GridPane.columnIndex="0" GridPane.rowIndex="1" />-->
        <!--<TextField GridPane.columnIndex="1" GridPane.rowIndex="1" />-->
        <!--<Button fx:id="test_button" text="Hello"></Button>-->
    </GridPane>
</VBox>

Application子类-在您的示例中是Main -实际上应该只是启动应用程序。也就是说,它应该加载FXML,把它放在一个窗口中,然后显示这个窗口。由FXML定义的UI的初始化和其他配置,以及事件处理,应该由控制器完成。因此,您实际上并没有尝试从正确的位置执行此代码。你应该从控制器中执行这个操作:

package soundboardEoZ;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
public class Controller {
    int index ;
    int target = 10;
    @FXML
    GridPane button_grid;
    public void initialize() {
        for (index = 2; index < target ; index++) {
            addButton();
        }
    }
    public void test(){
        System.out.println("Testing");
    }
    public void addButton(){
        Button sound_button = new Button("Button_" + index);
        button_grid.add(sound_button, index,2);
    }
}

然后从Main中删除所有功能:

package soundboardEoZ;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Main extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();

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

如果您真的想从Main调用该方法(但是,我再次强调,这实际上是在以与设计模式相反的方式使用工具包),创建一个FXMLLoader实例并从中获取控制器。您需要控制器正确地跟踪索引:

package soundboardEoZ;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
public class Controller {
    int index = 2;
    @FXML
    GridPane button_grid;
    public void test(){
        System.out.println("Testing");
    }
    public void addButton(){
        Button sound_button = new Button("Button_" + index);
        button_grid.add(sound_button, index,2);
        index++;
    }
}

然后你可以写:

package soundboardEoZ;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Main extends Application {
    int sound_index = 1;
    int target = 10;
    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
        Controller controller = loader.getController();
        while (sound_index < target){
            controller.addButton();
            sound_index++;
        }
    }
    public static void main(String[] args) {
        launch(args);
    }
}

最新更新