如何在javafx中分离我的gui?

时间:2016-07-20 00:27:46

标签: java javafx

通常当我创建我的gui时,我使用swing并创建我自己的类扩展jframe。然后我创建一个控制器类,并将我的程序基于mvc设计。但我最近决定试用javafx而且我有点失落。

目前我只需要在start方法的主类中使用我的所有gui,其中所有使用和引用的对象都在我的主类中声明为字段。这看起来非常混乱,并没有如此正确地实施。反正用javafx来做我以前用swing做的事情吗?

  • 我不想使用fxml,也不打算使用它。

2 个答案:

答案 0 :(得分:1)

一般来说,你有一个主要类,它只是启动GUI。 MVC的View部分由XML文件(称为FXML)处理。此FXML连接到控制器类。 JavaFX还允许您直接将所有GUI组件注入控制器内部的适当变量,因此您不需要查找它们。获取示例项目的最简单方法是使用maven archetypes for JavaFX

mvn archetype:generate -DarchetypeGroupId=com.zenjava -DarchetypeArtifactId=javafx-basic-archetype

只需转到项目所在的目录,该目录应该是上述命令的类型。然后它直接为您生成示例项目。所以让我们从主类开始

public class MainApp extends Application {

    private static final Logger log = LoggerFactory.getLogger(MainApp.class);

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

    public void start(Stage stage) throws Exception {

        log.info("Starting Hello JavaFX and Maven demonstration application");

        String fxmlFile = "/fxml/hello.fxml";
        log.debug("Loading FXML for main view from: {}", fxmlFile);
        FXMLLoader loader = new FXMLLoader();
        Parent rootNode = (Parent) loader.load(getClass().getResourceAsStream(fxmlFile));

        log.debug("Showing JFX scene");
        Scene scene = new Scene(rootNode, 400, 200);
        scene.getStylesheets().add("/styles/styles.css");

        stage.setTitle("Hello JavaFX and Maven");
        stage.setScene(scene);
        stage.show();
    }
}

如您所见,它只是加载FXMl并显示主窗口。 FXML指定GUI的可视结构(标签,文本字段,图像,按钮滚动条等)

<MigPane id="rootPane" fx:controller="example.HelloController" styleClass="main-panel" layout="insets 20" cols="[label, pref!][grow, 50::]" rows="" xmlns:fx="http://javafx.com/fxml">
    <Label text="First Name:" />
    <TextField fx:id="firstNameField" prefColumnCount="30" MigPane.cc="growx, wrap" />
    <Label text="Last Name:" /> <TextField fx:id="lastNameField" prefColumnCount="30" MigPane.cc="growx, wrap" />
    <Button text="Say Hello" onAction="#sayHello" MigPane.cc="skip, gap :push, gaptop 15, wrap" />
    <Label fx:id="messageLabel" styleClass="hello-message" MigPane.cc="span, growx, gaptop 15" />
</MigPane >

在FXML中指定用于将GUI与其逻辑分离的Controller,fx:id用于将元素直接注入控制器内的适当变量

public class HelloController
{
    private static final Logger log = LoggerFactory.getLogger(HelloController.class);

    @FXML private TextField firstNameField;
    @FXML private TextField lastNameField;
    @FXML private Label messageLabel;

    public void sayHello() {

        String firstName = firstNameField.getText();
        String lastName = lastNameField.getText();

        StringBuilder builder = new StringBuilder();

        if (!StringUtils.isEmpty(firstName)) {
            builder.append(firstName);
        }

        if (!StringUtils.isEmpty(lastName)) {
            if (builder.length() > 0) {
                builder.append(" ");
            }
            builder.append(lastName);
        }

        if (builder.length() > 0) {
            String name = builder.toString();
            log.debug("Saying hello to " + name);
            messageLabel.setText("Hello " + name);
        } else {
            log.debug("Neither first name nor last name was set, saying hello to anonymous person");
            messageLabel.setText("Hello mysterious person");
        }
    }

}

控制器具有带有@FXML注释的字段,这些注释是注入的GUI元素。您可以将变量名称等于fx:id,这是JavaFX注入元素所必需的。 要创建FXML,您可以使用Oracle Scene Builder或来自Gluon的两者都非常易于使用,并且可以让您快速生成漂亮的GUI。

答案 1 :(得分:1)

解决方案:创建一个扩展Scene的类,该类将stage作为param。移动将在main中的所有内容。这允许定期摆动mvc设计。

public class Main extends Application {

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

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

        CardModel model = new CardModel();
        CardView scene = new CardView(stage);       
        CardController controller= new CardController(model,scene);

        stage.setTitle("Title");
        stage.setMaximized(true);
        stage.setMinWidth(500);
        stage.setMinHeight(550);
        stage.setScene(scene);
        stage.show();
    }

}