我在试图让我的文本字段与我在控制器类中定义的ActionEvent句柄连接时遇到问题。这个错误是由java造成的。朗,反思一下。调用TargetException。我一直试图在视图中创建控制器类的实例,然后使用lamba方法引用调用控制器类中的handle方法。
查看类
package converter;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
public class View extends BorderPane{
private Controller control = new Controller(new Model(), new View());
//TextField
private TextField input = new TextField();
private TextField input2 = new TextField();
//RadioButton
private RadioButton distence = new RadioButton();
private RadioButton tempeture = new RadioButton();
private RadioButton weight = new RadioButton();
//ToggleGroup
private ToggleGroup group = new ToggleGroup();
public String getConversion()
{
return group.getSelectedToggle().getUserData().toString();
}
public double getInput()
{
return Double.parseDouble(input.getText());
}
public double getInput2()
{
return Double.parseDouble(input2.getText());
}
public void setInput(double value)
{
input.setText(Double.toString(value));
}
public void setInput2(double value)
{
input2.setText(Double.toString(value));
}
public View()
{
System.out.println(control);
//SetID
//input.setPromptText("Input");
//output.setPromptText("Output");
input.setId("input");
input2.setId("input2");
//SetUserData
distence.setUserData("dist");
tempeture.setUserData("temp");
weight.setUserData("weight");
//Set Label
distence.setText("Mile and Kilometer");
tempeture.setText("Celsius and Fahrenheit");
weight.setText("Pounds and Kilograms");
//SetGroup
distence.setToggleGroup(group);
tempeture.setToggleGroup(group);
weight.setToggleGroup(group);
//Add TextField ActionEvent
input.setOnAction(control::handle);
input2.setOnAction(control::handle);
//Add Group Listener
group.selectedToggleProperty().addListener((ov, o , n) ->{
// System.out.println(n.getUserData().toString());
String tog = n.getUserData().toString();
if (tog.equals("dist")) {
input.setPromptText("Mile");
input2.setPromptText("Kilometer");
}else if(tog.equals("temp")) {
input.setPromptText("Fahrenheit");
input2.setPromptText("Celsius");
}else if(tog.equals("weight")) {
input.setPromptText("Pound");
input2.setPromptText("Kilogram");
}
});
StackPane left = new StackPane();
StackPane right = new StackPane();
VBox leftbox = new VBox(3);
VBox rightbox = new VBox(2);
leftbox.setSpacing(5);
rightbox.setSpacing(10);
leftbox.getChildren().addAll(distence, tempeture, weight);
left.getChildren().add(leftbox);
rightbox.getChildren().addAll(input, input2);
right.getChildren().add(rightbox);
this.setLeft(left);
this.setRight(right);
}
}
控制器类
public class Controller implements EventHandler<ActionEvent>{
private Model model;
private View view;
public Controller(Model model, View view)
{
this.model = model;
this.view = view;
}
public Controller()
{
initalize();
}
public Controller initalize()
{
this.model = new Model();
this.view = new View();
return this;
}
@Override
public void handle(ActionEvent event)
{
String id = ((javafx.scene.Node)event.getSource()).getId();
String conversion = view.getConversion();
switch (id) {
case "input":
if(conversion.equals("dist")) {
view.setInput2(model.kilometer(view.getInput()));
break;
}else if(conversion.equals("temp")) {
view.setInput2(model.cToF(view.getInput()));
break;
}else if(conversion.equals("weight")) {
view.setInput2(model.kilogram(view.getInput()));
break;
}
case "input2":
if(conversion.equals("dist")) {
view.setInput(model.mile(view.getInput2()));
break;
}else if(conversion.equals("temp")) {
view.setInput(model.fToC(view.getInput2()));
break;
}else if(conversion.equals("weight")) {
view.setInput(model.pound(view.getInput2()));
break;
}
default:
break;
}
}
}
主课
package converter;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
private View view;
@Override
public void init()
{
Model model = new Model();
view = new View();
new Controller(model, view);
}
@Override
public void start(Stage primaryStage) {
try {
primaryStage.setMinWidth(350);
primaryStage.setMinHeight(150);
primaryStage.setScene(new Scene(view));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
堆栈跟踪
Exception in Application init method
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:465)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:364)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.RuntimeException: Exception in Application init method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:896)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:196)
at java.base/java.lang.Thread.run(Thread.java:831)
Caused by: java.lang.StackOverflowError
at javafx.graphics/javafx.scene.Node.getScene(Node.java:1148)
at javafx.graphics/javafx.scene.Node.updateCanReceiveFocus(Node.java:8502)
at javafx.graphics/javafx.scene.Node.setTreeVisible(Node.java:8420)
at javafx.graphics/javafx.scene.Node.updateTreeVisible(Node.java:8411)
at javafx.graphics/javafx.scene.Node.<init>(Node.java:2596)
at javafx.graphics/javafx.scene.Parent.<init>(Parent.java:1418)
at javafx.graphics/javafx.scene.layout.Region.<init>(Region.java:627)
at javafx.graphics/javafx.scene.layout.Pane.<init>(Pane.java:136)
at javafx.graphics/javafx.scene.layout.BorderPane.<init>(BorderPane.java:219)
at converter.View.<init>(View.java:52)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
at converter.View.<init>(View.java:12)
Exception running application converter.Main
您正在这里创建一个循环依赖项。控制器依赖于视图依赖于控制器。
这是糟糕的设计。
您应该实现控制的反转,并依赖于抽象。抽象要么是在视图的构建中给出的,要么是有html" target="_blank">工厂或某个依赖注入框架。另一个选择是让你的视图发出控制器订阅的特定视图事件。有很多方法可以正确解决这个问题——循环依赖不是其中之一。
抽象应该是尽可能最小的完整抽象(接口隔离原则),所以如果你需要一个处理程序,你可以有一个带有句柄(事件)
函数的接口,仅此而已。
这并不禁止控制器实现句柄功能,它可能违反单一责任原则,但这将取决于控制器的问题和实现。
请参见此处的实体原则:维基百科实体
更新:您就快到了,只需添加setEventHandler作为视图属性。
public void setEventHandler(@NotNull EventHandler handler) {
this.handler = handler;
updateHandler();
}
private void updateHandler() {
//Add TextField ActionEvent
input.setOnAction(handler::handle);
input2.setOnAction(handler::handle);
}
并将其添加到您的Main::init
中:
Controller controller = new Controller(model , view);
view.setEventHandler(controller);
还必须修复控制器的默认构造函数。
出现异常是因为在构造视图
实例时存在无限递归:
public class View {
// ...
private Controller control = new Controller(new Model(), new View());
// ...
}
当你创建一个视图
实例时,你会尝试创建一个新的视图
实例(传递给控制器
构造函数),这反过来会创建一个新的视图
实例,传递给控制器
构造函数,等等。即使你消除了这里的依赖关系,你也希望这些对象引用同一个实例;你不想到处创建新的实例。
MVC有几种不同的变体。看起来您正在尝试实现一个“传统”的MVC,其中:
所以:
我还建议不要让控制器实现任何EventHandler
接口;只需定义处理用户输入所需的方法。为每个用户操作定义单独的方法,而不是使用一个带有无休止的开关
或if-else
语句的单一handle()
方法。
比如:
public class View {
private final Controller controller ;
private final Model model ;
private final TextField input ;
private final TextField input2 ;
// ...
public View(Model model, Controller controller) {
this.model = model ;
this.controller = controller ;
input = new TextField();
input2 = new TextField();
model.someProperty().addListener((obs, oldValue, newValue) -> {
/* update controls */
});
model.someOtherProperty().addListener((obs, oldValue, newValue) -> {
/* update controls */
});
input.setOnAction(event -> controller.handleInput(input.getText()));
input2.setOnAction(event -> controller.handleInput2(input2.getText()));
// layout etc
}
}
public class Controller {
public final Model model ;
public Controller(Model model) {
this.model = model ;
}
public void handleInput(String input) {
model.setSomeValue(input);
}
public void handleInput2(String input) {
model.setSomeOtherValue(input2);
}
// etc
}
然后用下面的代码来组装它
Model model = new Model();
Controller controller = new Controller(model);
View view = new View(model, controller);
有关完整的示例,请参阅在不使用FXML的情况下使用JavaFX控制器。
问题内容: 在PHP系统中,我有一个常见的MVC情况:从包含的数据中接收请求。现在,我有三种方法来处理数据: a)仅调用和处理数据。 b)在变换的数据转换成变量,并将它们传递到。 c)将数据转换为的域对象,并将该对象仅传递给。 目前,我正在使用选项A,但是我认为这是错误的,因此我正在考虑使用选项C。 因此,根据MVC,处理数据的正确方法是什么? 编辑 目前,我没有使用任何MVC框架。 编辑2 通常
问题内容: 我的代码如下: 如果在获取之前设置标题,可以吗?我的标头会被发送,还是服务器会看到默认的用户代理(如果有)? 问题答案: 必须 先设置标头,然后才能产生任何影响- 如果连接已经打开,则将引发。 就头而言,如果已设置,则应将其发送。 请参阅URLConnection JavaDoc。
问题内容: 我一直在使用spring-webflux进行一些研究,我想了解使用路由器功能处理错误的正确方法。 我创建了一个小项目来测试几个场景,并且我希望获得有关它的反馈,并查看其他人在做什么。 到目前为止,我在做什么。 提供以下路由功能: 我已经在我的处理程序上执行了 它们是我的错误处理程序: 这是完整的示例存储库: https://github.com/LearningByExample/re
问题内容: 我使用10gen的本机node.js驱动器将mongodb(2.2.2)与node.js一起使用。 起初一切顺利。但是当涉及到并发基准测试部分时,会发生很多错误。频繁进行1000次并发连接/关闭可能会导致mongodb拒绝任何进一步的请求,并出现以下错误: 另外,如果许多客户端在没有显式关闭的情况下关闭,则mongodb将花费几分钟的时间来检测并关闭它们。这也将导致类似的连接问题。(使
我试试看。js与mongodb(2.2.2)一起使用本机节点。js drive by 10gen。 起初一切都很顺利。但在并发基准测试部分,出现了很多错误。频繁连接/关闭1000次并发可能会导致mongodb拒绝任何进一步的请求,错误如下: 此外,如果很多客户端在没有显式关闭的情况下关闭,mongodb需要几分钟来检测并关闭它们。这也会导致类似的连接问题。(使用/var/log/mongodb/m
问题内容: 我在Django 1.6上无法正常使用翻译存在问题。我已将此添加到我的settings.py中: 还添加了中间件: 以及每当我使用应为l10nd的字符串时的* .py文件: 我的模板开始于: 在模板内部,我使用了trans占位符。例如 我在locale / de / LC_MESSAGES / django.po中提供了翻译: 问题答案: 添加到并将其设置如下: 请注意,它必须是一个元