Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javafx应用程序实例化后,如何更改其变量值?_Java_Javafx - Fatal编程技术网

在javafx应用程序实例化后,如何更改其变量值?

在javafx应用程序实例化后,如何更改其变量值?,java,javafx,Java,Javafx,我正在尝试创建一个可以用于未来项目的通用类。它只是一个简单的javafx浏览器。我遇到的问题是,我希望能够动态地(在实例化时)更改某些属性。我添加了一些简单的二传手,希望它能应用到工作中,但它们不起作用。执行start()后,是否有方法更改变量 类别代码: package rob.rushton; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.layout.Border

我正在尝试创建一个可以用于未来项目的通用类。它只是一个简单的javafx浏览器。我遇到的问题是,我希望能够动态地(在实例化时)更改某些属性。我添加了一些简单的二传手,希望它能应用到工作中,但它们不起作用。执行start()后,是否有方法更改变量

类别代码:

package rob.rushton;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

public class RushBrowser extends Application {

    public RushBrowser() {}

    private String url = "www.google.com";
    private final String fullUrl = "http://" + url;
    String title = "Simple Browser";
    private int height = 750;
    private int width = 750;

    public void openBrowser() {
        launch();
    }

    public void setURL(String u) {
        url = u;
    }

    public void setHeightWidth(int h, int w) {
        height = h;
        width = w;
    }

    public void setTitle(String t) {
        title = t;
    }

    @Override
     public void start(Stage stage) {
        stage.setTitle(this.title);
        BorderPane pane = new BorderPane();
        Scene scene = new Scene(pane, width, height);
        WebView browser = new WebView();
        WebEngine engine = browser.getEngine();
        engine.load(fullUrl);
        pane.setCenter(browser);
        stage.setScene(scene);
        stage.show();
    }
}
我试着这样运行它:

package rushtest;

import rob.rushton.RushBrowser;

public class RushTest {

    public static void main(String[] args) {
        RushBrowser rush = new RushBrowser();
        rush.setTitle("Test Title");
        rush.setURL("www.github.com");
        rush.setHeightWidth(1000, 1000);
        rush.openBrowser();
    }    
}

编辑:(8/9/15)下面列出的建议都不起作用:(问题是我不知道如何访问由launch()启动的应用程序线程)

您应该将这些属性设置为真实的JavaFX属性,或者将它们的setter委托给实际的UI对象。一些粗略的代码-仅显示相关部分:

真实JavaFX属性的情况:

public class RushBrowser extends Application {

    ...
    private StringProperty titleProperty = new SimpleStringProperty("Simple Browser");
    ...

    public void setTitle(String t) {
        titleProperty.set(t);
    }

    @Override
     public void start(Stage stage) {
        stage.titleProperty().bind(this.titleProperty);
        ...
    }
}
授权情况-您还必须保留
阶段的参考:

public class RushBrowser extends Application {

    ...
    private Stage primaryStage;
    // no need to keep the title member variable
    ...

    public void setTitle(String t) {
        primaryStage.setTitle(t);
    }

    @Override
    public void start(Stage stage) {
        this.primaryStage = stage;
        ...
    }
}

编辑

根据James_D的评论,还有一个问题:main方法没有引用由
Application.launch()
创建的实例。因此:

  • 如果要在应用程序启动前自定义其参数,可以覆盖
    application.init()

    或从测试代码:

    public class RushTest {
        static class TestRushBrowser extends RushBrowser {
            public void init() {
                super.init(); // just in case
                this.setTitle("Test Title");
                ...
            }
        }
    
        public static void main(String[] args) {
            TestRushBrowser.launch();
        }
    }
    
    如果以后不需要修改这些参数,可以保持代码不变(即不需要JavaFX属性)。否则,应用上述更改

  • 如果要在应用程序启动后更改参数,则需要提供对由
    application.launch()
    创建的
    RushBrowser
    的实际实例的引用,以执行更改的代码。一种简单但不干净的方法是使用全局变量:

    public class RushBrowser extends Application {
        public static RushBrowser INSTANCE;
    
        public void init() {
            INSTANCE = this;
        }
    
        ...
    }
    
    然后从
    launch()
    之后运行的任何代码:

    由于全局状态通常是危险的,如果应用程序变得更复杂,您可能希望尝试使用依赖注入框架。即使使用DI,也可能会变得棘手,因为主类仍然是在DI框架之外从JavaFX创建的,但这是另一种情况

    同样,您需要在编辑上方应用更改


  • 您发布的代码不起作用的原因是(
    static
    launch(…)
    方法为您创建一个
    应用程序
    子类的新实例,然后调用其
    start(…)
    方法。因此,您调用所有
    setXXX(…)的实例
    methods不是调用其
    start(…)
    方法的实例

    您在错误的地方定义了可重用部分:
    应用程序
    子类本质上是不可重用的。您应该将
    应用程序
    子类中的
    start()
    方法视为常规JavaFX应用程序中的
    main()
    方法的等价物

    因此:

    然后使用
    应用程序
    子类对其进行测试:

    public class RushBrowserTest extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            RushBrowser rush = new RushBrowser();
            rush.setTitle("Test Title");
            rush.setURL("www.github.com");
            rush.setHeightWidth(1000, 1000);
            rush.show(primaryStage);
        }
    
        public static void main(String[] args) { launch(args); }
    }
    
    当然,你也可以在其他地方使用它。作为一个任意的例子:

    TabPane tabPane = ... ;
    
    RushBrowser rush = new RushBrowser();
    rush.setURL("www.github.com");
    Tab tab = new Tab();
    tab.setContent(rush.getView());
    

    这并不能解决问题,不是吗?(问题是由
    launch()
    方法创建的实例与OP设置值的实例不同。)您将如何运行它?@James_D是的,您是对的;这解决了一半问题,即正确引用了
    RushBrowser
    ,实际设置了它的属性。更新答案…@NikosParaskevopoulos是“stage.titleProperty.bind(this.titleProperty);”正确的语法?@RobRushton您是对的,它实际上是一个方法,因此应该是
    stage.titleProperty()…
    ->在回答中更正。
    public class RushBrowser {
    
        private final BorderPane view ;
    
        private String url = "www.google.com";
        private final String fullUrl = "http://" + url;
        private String title = "Simple Browser";
        private int height = 750;
        private int width = 750;
    
        private WebEngine engine ;
    
        public RushBrowser() {
            WebView browser = new WebView();
            view = new BorderPane(browser);
            engine = browser.getEngine();
        }
    
        public Node getView() {
            return view ;
        }
    
        public void show(Stage stage) {
            Scene scene = new Scene(view, width, height);
            stage.setScene(scene);
            stage.show();
        }
    
        public void show() {
            show(new Stage());
        }
    
        public void setURL(String u) {
            url = u;
        }
    
        public void setHeightWidth(int h, int w) {
            height = h;
            width = w;
            view.setPrefSize(w, h);
        }
    
        public void setTitle(String t) {
            title = t;
            Scene scene = view.getScene();
            if (scene != null) {
                Window window = scene.getWindow();
                if (window instanceof Stage) {
                    ((Stage)window).setTitle(title);
                }
            } 
        }
    }
    
    public class RushBrowserTest extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            RushBrowser rush = new RushBrowser();
            rush.setTitle("Test Title");
            rush.setURL("www.github.com");
            rush.setHeightWidth(1000, 1000);
            rush.show(primaryStage);
        }
    
        public static void main(String[] args) { launch(args); }
    }
    
    TabPane tabPane = ... ;
    
    RushBrowser rush = new RushBrowser();
    rush.setURL("www.github.com");
    Tab tab = new Tab();
    tab.setContent(rush.getView());