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