javafx中已经创建的scene的宽高能改变吗?怎么改呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javafx中已经创建的scene的宽高能改变吗?怎么改呢?相关的知识,希望对你有一定的参考价值。

参考技术A 这种要并排放置的情况就把一个HBox对象设为Scene的root,然后再把两个panel放到HBox上即可。由于你只是要界面,计算器的计算逻辑我就不实现了,具体代码如下(运行环境:jdk8或以上): import javafx.application.Application; import javafx.g
javafx,scene,高能
这种要并排放置的情况就把一个HBox对象设为Scene的root,然后再把两个panel放到HBox上即可。由于你只是要界面,计算器的计算逻辑我就不实现了,具体代码如下(运行环境:jdk8或以上): import javafx.application.Application; import javafx.g追问

你粘贴的?都读不通

我想把1000x800的scene改成640x480,怎么改?

参考技术B

一般我们在编写javaFX程序时,宽高都是开发者初始化好的。如果我们要想在使用过程中改变程序的宽高时,可以有两种方式。

    拖拉程序的边框。(使用窗体默认的事件来改变)

    我们可以手动通过代码去改变(直接改变舞台大小即可,不去设置场景大小)

    stage.setWidth(1000);

    stage.setHeight(800);

在需要的地方,调用上面两行代码即可(stage: 程序对应的舞台)。如果代码还是出错的话,有可能是 stage 作用域的问题,这时我们需要提高 stage 的作用域。【具体使用如下】

参考技术C 追问

我想把1000x800的scene改成640x480,怎么改?

使用Scene Builder 8.0在JavaFX中使用setCenter()方法获取Null Pointer Exception

我创建了一个小程序来重现我在实际项目中得到的错误。我有一个名为MainWindow.java的控制器类,它负责两个.fxml文件:MainWindow.fxmlAnchorTest.fxml。 控制器类的代码:

package projecterror.controller;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class MainWindow extends Application {

    private Stage primaryStage;
    private BorderPane mainWindow;

    @FXML
    Menu menuFile, menuAnalysis;
    @FXML
    MenuItem menuNew;


    @FXML
    private void initialize() {
        menuNew.setOnAction((event) -> {
            try {
                FXMLLoader loader = new FXMLLoader();
                loader.setLocation(getClass().getResource("../view/AnchorTest.fxml"));
                AnchorPane anchorTest = (AnchorPane) loader.load();
                mainWindow.setCenter(anchorTest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("Test Project");

        initMainWindow();

    }

    public void initMainWindow() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("../view/MainWindow.fxml"));
            mainWindow = (BorderPane) loader.load();

            Scene scene = new Scene(mainWindow);
            primaryStage.setScene(scene);

            //Fullscreen
            Screen screen = Screen.getPrimary();
            Rectangle2D bounds = screen.getVisualBounds();
            primaryStage.setX(bounds.getMinX());
            primaryStage.setY(bounds.getMinY());
            primaryStage.setWidth(bounds.getWidth());
            primaryStage.setHeight(bounds.getHeight());

            primaryStage.setResizable(false);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

MainWindow.fxmlBorderPane,在MenuBar上有top。 码:

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

<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.layout.BorderPane?>

<BorderPane style="-fx-background-color: #DCDCDC;" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="projecterror.controller.MainWindow">
    <top>
      <MenuBar BorderPane.alignment="CENTER">
        <menus>
          <Menu fx:id="menuFile" mnemonicParsing="false" text="File">
            <items>
                  <Menu fx:id="menuAnalysis" mnemonicParsing="false" text="Analysis">
                    <items>
                      <MenuItem fx:id="menuNew" mnemonicParsing="false" text="New" />
                    </items>
                  </Menu>
            </items>
          </Menu>
        </menus>
      </MenuBar>
   </top>
</BorderPane>

AnchorTest.fxml是一个AnchorPane,有孩子两个AnchorPane

码:

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

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

<AnchorPane xmlns:fx="http://javafx.com/fxml/1">
    <children>
            <AnchorPane layoutX="6.0" layoutY="450.0" />
            <AnchorPane layoutX="6.0" layoutY="569.0" prefHeight="116.0" prefWidth="730.0">
                  <Button layoutX="6.0"   layoutY="26.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="102.0" text="Button 1" />
                  <Button layoutX="115.0" layoutY="26.0" mnemonicParsing="false" prefWidth="102.0" text="Button 2" />
                  <Button layoutX="226.0" layoutY="26.0" mnemonicParsing="false" prefWidth="102.0" text="Button 3" />
                  <Button layoutX="115.0" layoutY="75.0" mnemonicParsing="false" prefWidth="102.0" text="Button 4" />
                  <Button layoutX="383.0" layoutY="26.0" mnemonicParsing="false" prefWidth="102.0" text="Button 5" />
                  <Button layoutX="491.0" layoutY="26.0" mnemonicParsing="false" prefWidth="102.0" text="Button 6" />
                  <Button layoutX="600.0" layoutY="26.0" mnemonicParsing="false" prefWidth="102.0" text="Button 7" />
                  <Button layoutX="491.0" layoutY="75.0" mnemonicParsing="false" prefWidth="102.0" text="Button 8" />
                  <Button layoutX="600.0" layoutY="75.0" mnemonicParsing="false" prefWidth="102.0" text="Button 9" />
                  <TextField alignment="TOP_CENTER" layoutX="341.0" layoutY="26.0" prefHeight="25.0" prefWidth="28.0" text="10" />
            </AnchorPane>
         </children>
</AnchorPane>

MainWindow.fxml上,点击菜单File > Analysis > New后,它应该将AnchorTest.fxml内容放入MainWindow.fxml中心。但是,我收到以下堆栈跟踪错误:

 Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
        at projecterror.controller.MainWindow.lambda$0(MainWindow.java:35)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
        at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
        at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
        at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
        at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
        at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
        at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
        at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
        at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
        at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
        at javafx.event.Event.fireEvent(Event.java:198)
        at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
        at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
        at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
        at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:380)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416)
        at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
        at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415)
        at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
        at com.sun.glass.ui.View.notifyMouse(View.java:937)
        at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
        at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
        at java.lang.Thread.run(Thread.java:745)

标记NPE的行是:

mainWindow.setCenter(anchorTest);

我已经阅读了与此类似的其他问题,但大部分问题都与fxml文件的路径有关。我坚信这不是问题,因为在我的实际项目中,我对其他视图使用相同类型的路径,到目前为止我没有问题。 我上传了项目here以防有人想要运行该程序。 项目结构如下: Project structure 在此先感谢,任何帮助将不胜感激!

答案

当您启动JavaFX应用程序时,会创建一个应用程序类的实例,并且(在其他情况下)会在FX应用程序线程上的start()实例上调用Application方法。

加载FXML文件时,如果FXML文件指定了控制器类,则创建该控制器类的实例,将@FXML-annotated字段注入该实例,并调用initialize()方法。所有这些都发生在对FXMLLoader.load()的调用期间。

因此,在您的代码中,您最终会得到两个不同的MainWindow实例。在一个实例上调用start()方法,该实例初始化mainWindow字段,并在另一个实例上调用initialize()方法。由于mainWindow从未在第二个实例中初始化,因此当您尝试在initialize()方法中取消引用时,会得到空指针异常。

将控制器类与Application类分开。除了管理整个应用程序的生命周期之外,Application类应该什么都不做(通常,它应该实现启动应用程序所需的代码):

package projecterror.controller;

import java.io.IOException;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class MainWindow extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Test Project");

        initMainWindow(primaryStage);

    }

    public void initMainWindow(Stage primaryStage) {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(getClass().getResource("../view/MainWindow.fxml"));
            BorderPane mainWindow = loader.load();

            Scene scene = new Scene(mainWindow);
            primaryStage.setScene(scene);

            //Fullscreen
            Screen screen = Screen.getPrimary();
            Rectangle2D bounds = screen.getVisualBounds();
            primaryStage.setX(bounds.getMinX());
            primaryStage.setY(bounds.getMinY());
            primaryStage.setWidth(bounds.getWidth());
            primaryStage.setHeight(bounds.getHeight());

            primaryStage.setResizable(false);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
package projecterror.controller;

import java.io.IOException;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;

public class MainWindowController {

    @FXML
    private BorderPane mainWindow;

    @FXML
    Menu menuFile, menuAnalysis;
    @FXML
    MenuItem menuNew;


    @FXML
    private void initialize() {
        menuNew.setOnAction((event) -> {
            try {
                FXMLLoader loader = new FXMLLoader();
                loader.setLocation(getClass().getResource("../view/AnchorTest.fxml"));
                AnchorPane anchorTest = (AnchorPane) loader.load();
                mainWindow.setCenter(anchorTest);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }



}

为了让控制器访问BorderPane,您需要从FXML中注入它(请注意上面控制器代码中的注释)。将fx:id添加到FXML文件中的元素:

<BorderPane style="-fx-background-color: #DCDCDC;" fx:id="mainWindow"
    xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" 
    fx:controller="projecterror.controller.MainWindowController">

以上是关于javafx中已经创建的scene的宽高能改变吗?怎么改呢?的主要内容,如果未能解决你的问题,请参考以下文章

自定义 JavaFX 控件 - Scene Builder 2.0 中的“已指定根值”

如何填充在 JavaFx Scene Builder 中设计的 fxml 文件中定义的 TableView

JAvaFX元素调整大小以适应Window

使用Scene Builder 8.0在JavaFX中使用setCenter()方法获取Null Pointer Exception

导入 javafx.scene.control.Alert 无法解析

javafx scene builider 使用总结