我有以下代码
TTTControl类:
public class TTTControl extends Application implements EventHandler<ActionEvent> {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
String resource = "TTTGui.fxml";
Parent root = FXMLLoader.load(getClass().getResource(resource));
int window_width = 800;
int window_height = 380;
stage.setScene(new Scene(root, window_width, window_height));
stage.show();
}
@Override
public void handle(ActionEvent event) {
// Könnte man ggfs. in der Zukunft noch benutzen
System.out.println("Event!");
}
}
控制器类:
public class Controller {
int n = 3;
Button buttons[][] = new Button[n][n];
EventManager em = new EventManager();
Controller() throws Exception {
String resource = "TTTGui.fxml";
Parent root = FXMLLoader.load(getClass().getResource(resource));
for (int i=0; i < this.n; i++) {
for (int j=0; j < this.n; j++) {
String row = Integer.toString(i);
String col = Integer.toString(j);
Button btn = (Button) root.lookup("#"+row+col);
btn.setStyle("-fx-base: white;");
this.buttons[i][j] = btn;
}
}
}
// Funktion die beim Klicken eines Buttons mit dem onAction="#buttonPressed" Attribut ausgeführt wird
public void buttonPressed(ActionEvent event) {
if (((Button) event.getSource()).getStyle() == "-fx-base: green;" ||
((Button) event.getSource()).getStyle() == "-fx-base: red;") {
// der Vollständigkeit halber wird hier auch noch ausgegeben, dass es zwar ein ClickEvent gab, aber das Feld schon belegt war
System.out.println("Spieler 1 hat " + ((Button) event.getSource()).getId() + " gedrückt.");
System.out.println("Dieses Feld ist jedoch schon besetzt.");
} else {
if (em.getActivePlayer() == "One") {
System.out.println("Spieler 1 hat " + ((Button) event.getSource()).getId() + " gedrückt.");
((Button) event.getSource()).setStyle("-fx-base: green;");
em.setActivePlayer("Two");
if (em.checkWin("-fx-base: green;", this.buttons) == true) {
System.out.println("Spieler Eins hat gewonnen!");
neuesSpiel();
}
} else if (em.getActivePlayer() == "Two") {
System.out.println("Spieler 1 hat " + ((Button) event.getSource()).getId() + " gedrückt.");
((Button) event.getSource()).setStyle("-fx-base: red;");
em.setActivePlayer("One");
if (em.checkWin("-fx-base: red;", this.buttons) == true) {
System.out.println("Spieler Zwei hat gewonnen!");
neuesSpiel();
}
}
}
}
}
eventmanager进行:
public class EventManager {
private String activePlayer;
// Konstruktur von der Klasse mit ein paar Variablen die initialisiert werden
EventManager() {
this.activePlayer = "One";
}
public boolean checkWin(String color, Button[][] buttons) {
// [Reihe][Spalte]
// horizontal
if (buttons[0][0].getStyle() == color && buttons[0][1].getStyle() == color && buttons[0][2].getStyle() == color) {
return true;
}
else if (buttons[1][0].getStyle() == color && buttons[1][1].getStyle() == color && buttons[1][2].getStyle() == color) {
return true;
}
else if (buttons[2][0].getStyle() == color && buttons[2][1].getStyle() == color && buttons[2][2].getStyle() == color) {
return true;
}
// vertikal
else if (buttons[0][0].getStyle() == color && buttons[1][0].getStyle() == color && buttons[2][0].getStyle() == color) {
return true;
}
else if (buttons[0][1].getStyle() == color && buttons[1][1].getStyle() == color && buttons[2][1].getStyle() == color) {
return true;
}
else if (buttons[0][2].getStyle() == color && buttons[1][2].getStyle() == color && buttons[2][2].getStyle() == color) {
return true;
}
// diagonal
else if (buttons[0][0].getStyle() == color && buttons[1][1].getStyle() == color && buttons[2][2].getStyle() == color) {
return true;
}
else if (buttons[0][2].getStyle() == color && buttons[1][1].getStyle() == color && buttons[2][0].getStyle() == color) {
return true;
}
return false;
}
// Getter und Setter Methoden für die private Variablen
public void setActivePlayer(String activePlayer) {
this.activePlayer = activePlayer;
}
public String getActivePlayer() {
return this.activePlayer;
}
}
所以,我尝试创建一个控制器类,例如应该处理所有按钮事件(我猜这是控制器在这种情况下的用途)。因为我需要Parent root
我猜测将根注入控制器意味着再次在那个地方加载它.... Buuut这不起作用我得到了跟随< / p>
错误:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.launcher.LauncherHelper$FXHelper.main(Unknown Source)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$155(LauncherImpl.java:182)
at java.lang.Thread.run(Unknown Source)
Caused by: javafx.fxml.LoadException:
/C:/Users/Ibrahim/git/nicolle_informatik/bin/vl06/TTTGui.fxml:21
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2601)
at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:934)
at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:971)
at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:220)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:744)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2707)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at vl06.TTTControl.start(TTTControl.java:20)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Caused by: java.lang.IllegalAccessException: Class sun.reflect.misc.ReflectUtil can not access a member of class vl06.Controller with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:927)
... 22 more
Exception running application vl06.TTTControl
答案 0 :(得分:1)
出现异常是因为控制器中的构造函数不是公共的。
您的代码中还有许多其他错误。
您正在加载控制器中FXML中定义的UI的第二个副本:
Controller() throws Exception {
String resource = "TTTGui.fxml";
Parent root = FXMLLoader.load(getClass().getResource(resource));
// ...
}
这将创建FXML文件的根元素的第二个实例,以及其中包含的所有内容的新实例。显然,这与您在Scene
方法中start
中显示的实例不同。因此按钮与显示的按钮不同,按钮上的配置无效。
您需要使用FXML中常用的fx:id
属性将根元素注入控制器,并使用@FXML
注释:
public class Controller {
int n = 3;
Button buttons[][] = new Button[n][n];
EventManager em = new EventManager();
@FXML
private Parent root ;
// ...
}
然后将fx:id="root"
添加到FXML文件的根元素。
此外,您试图在控制器的构造函数中引用FXML的元素,而不是initialize()
方法。如描述here,必须在注入FXML中定义的元素之前调用构造函数,因此不能在那里访问它们。
所以你需要像
这样的东西public class Controller {
int n = 3;
Button buttons[][] = new Button[n][n];
EventManager em = new EventManager();
@FXML
private Parent root ;
public void initialize() {
for (int i=0; i < this.n; i++) {
for (int j=0; j < this.n; j++) {
String row = Integer.toString(i);
String col = Integer.toString(j);
Button btn = (Button) root.lookup("#"+row+col);
btn.setStyle("-fx-base: white;");
this.buttons[i][j] = btn;
}
}
}
// ...
}
最后,您有一些基本的Java错误,超出了本问题的范围。例如。你应该阅读How do I compare strings in Java?