Hallo Liebe Community,
ich habe schon viel hier im Forum gelesen und konnte schon viele gute Tipps und Tricks auch herauslesen.
Leider konnte ich zu meinem aktuellen Problem keine Lösung finden.
Es geht darum, das ich im Zuge eines OnlineStudiums ein Hangman Spiel programmiert habe.
So weit so gut, den Quellcode musste ich nur abtippen und hatte dann alles vor mir.
Leider kam aber beim Start dann ein Fehler "java.lang.IllegalAccessError"
Da ich mir nicht sicher war ob ich einen Fehler beim abtippen gemacht habe, hab ich den Quellcode aus dem Studienheft heraus kopiert und es noch einmal probiert. Auch hier das gleiche Ergebnis.
Mein letzter Versuch war, die Projektdateien aus dem Downloadbereich des Onlinestudiums zu holen und in Eclipse zu importieren. Selbst mit den Originaldateien kam wieder der gleiche Fehler.
Jetzt ist meine Hoffnung das hier jemand den Fehler im Code sieht und mir die Augen öffnen kann.
Hier die FXML Main Klasse:
Das ist der FXML Controller:
Und hier noch die FXML Datei mit der UI:
Anfangs hatte ich das Problem den Controller mit der UI zu verbinden (mache das über den SceneBuilder Version 11.0.0).
Es hat erst geklappt als ich das Standardpaket in Java verwendet habe, spezifische Pakete konnte ich nicht erstellen.
Ich hoffe ich habe nicht zu verwirrend geschrieben. Da das hier mein erster Post ist, muss ich mich noch etwas einarbeiten.
Achja, hier noch die Fehlermeldung die angezeigt wird:
ich habe schon viel hier im Forum gelesen und konnte schon viele gute Tipps und Tricks auch herauslesen.
Leider konnte ich zu meinem aktuellen Problem keine Lösung finden.
Es geht darum, das ich im Zuge eines OnlineStudiums ein Hangman Spiel programmiert habe.
So weit so gut, den Quellcode musste ich nur abtippen und hatte dann alles vor mir.
Leider kam aber beim Start dann ein Fehler "java.lang.IllegalAccessError"
Da ich mir nicht sicher war ob ich einen Fehler beim abtippen gemacht habe, hab ich den Quellcode aus dem Studienheft heraus kopiert und es noch einmal probiert. Auch hier das gleiche Ergebnis.
Mein letzter Versuch war, die Projektdateien aus dem Downloadbereich des Onlinestudiums zu holen und in Eclipse zu importieren. Selbst mit den Originaldateien kam wieder der gleiche Fehler.
Jetzt ist meine Hoffnung das hier jemand den Fehler im Code sieht und mir die Augen öffnen kann.
Hier die FXML Main Klasse:
Java:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HangmanFX extends Application{
@Override
public void start(Stage meineStage) throws Exception {
//die Datei laden
Parent root = FXMLLoader.load(getClass().getResource("sb_hangman.fxml"));
//die Szene erzeugen
//an den Konstruktor werden der oberste Knoten und die Größe übergeben
Scene meineScene = new Scene(root, 350, 450);
//den Titel über stage setzen
meineStage.setTitle("Hangman");
//die Szene setzen
meineStage.setScene(meineScene);
//und anzeigen
meineStage.show();
}
public static void main(String[] args) {
//der Start
launch(args);
}
}
Das ist der FXML Controller:
Code:
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
public class FXMLController {
//das Kombinationsfeld
@FXML private ComboBox<String> auswahl;
//die Labels für die Ausgaben
@FXML private Label ausgabeText;
@FXML private Label anzVersuche;
//für die Zeichenfläche
@FXML private Canvas zeichenflaeche;
//ein Array mit Zeichenketten(!) für die Buchstaben
private String [] zeichen = new String[26];
//ein StringBuilder für die Darstellung des Suchwortes
private StringBuilder anzeige;
//ein String für das gesuchte Wort im Klartext
private String suchwort;
//für die verbleibenden Durchläufe
private int restDurchlauefe;
//für die Anzahl der Fehler
private int fehler;
//für den Grafikkontext
private GraphicsContext gc;
//die Methode zur Auswahl aus dem Kombinationsfeld
@FXML protected void auswahlNeu(ActionEvent event) {
//der aktuell ausgewählte Eintrag wird übergeben und ausgewertet
pruefen(auswahl.getSelectionModel().getSelectedItem());
//ist das Spiel zu Ende oder nicht?
gewinnerOderNicht();
}
//die Methode zum Beenden
@FXML protected void beendenKlick(ActionEvent event) {
Platform.exit();
}
//die Methode setzt die Initialwerte
//sie wird automatisch ausgeführt
@FXML void initialize() {
int tempIndex = 0;
//es geht los mit 9 verbleibenden Durchläufe
restDurchlauefe = 9;
//die restlichen Durchläufe anzeigen
anzVersuche.setText(Integer.toString(restDurchlauefe));
//die Liste für das Kombinationsfeld füllen
for (char temp = 'a'; temp <= 'z'; temp++) {
zeichen[tempIndex] = Character.toString(temp);
tempIndex++;
}
auswahl.getItems().addAll(zeichen);
//ein Wort ermitteln
neuesWort();
//den Grafikkontext beschaffen
gc = zeichenflaeche.getGraphicsContext2D();
}
//die Methode ermittelt zufällig ein Wort
private void neuesWort() {
int zufall = 0;
//die Wortliste
String[] woerter ={"Test", "Automobil", "Versuch", "Hund", "Katze",
"Ziege", "Maus", "Elefant", "Isopropylalkohol", "Schwimmbad"};
//ein zufälliges Wort ermitteln
//dazu wird eine zufällige Zahl zwischen 0 und 1 ermitteln und mit der Länge von woerter multipliziert
zufall = (int)(Math.random() * woerter.length);
//das Suchwort und die Zeichen für die Anzeige setzen
suchwort = new String(woerter[zufall]);
anzeige = new StringBuilder(suchwort);
//alle Zeichen in der Anzeige ersetzen durch *
for (int zeichen = 0; zeichen < suchwort.length(); zeichen++)
anzeige.setCharAt(zeichen, '*');
//die Sternchen anzeigen
ausgabeText.setText(anzeige.toString());
}
//die Methode zum Prüfen
private void pruefen(String auswahlZeichen) {
char zeichen;
int treffer = 0;
//das ausgewählte Zeichen aus dem Kombinationsfeld umbauen
zeichen = auswahlZeichen.charAt(0);
//gibt es das Zeichen auch im Suchwort?
//dabei vergleichen wir nur die Kleinbuchstaben
treffer = suchwort.toLowerCase().indexOf(zeichen);
//wenn wir nichts gefunden haben
if (treffer < 0) {
//1 von den verbleibenden Durchläufen abziehen
restDurchlauefe--;
//die restlichen Durchläufe anzeigen
anzVersuche.setText(Integer.toString(restDurchlauefe));
//die Fehler für die Anzeige erhöhen und den Galgen zeichnen
erhoeheFehler();
}
else {
//nach weiteren Vorkommen suchen
while (treffer >= 0) {
//das Zeichen aus der entsprechenden Position im Suchwort anzeigen
anzeige.setCharAt(treffer, suchwort.charAt(treffer));
//treffer erhöhen und dann weitersuchen
treffer++;
treffer = suchwort.toLowerCase().indexOf(zeichen,treffer);
}
//das geänderte Wort anzeigen
ausgabeText.setText(anzeige.toString());
}
}
private void gewinnerOderNicht() {
//die Linienbreite auf 1 setzen
gc.setLineWidth(1);
//ist das Spiel zu Ende?
if (restDurchlauefe == 0) {
gc.strokeText("Das gesuchte Wort war: " + suchwort, 20, 100);
Platform.exit();
}
//ist das Wort erraten worden?
if (anzeige.toString().equals(suchwort)) {
gc.strokeText("Hurra! Sie haben gewonnen!", 20, 100);
Platform.exit();
}
}
//Fehler hochzählen und den Galgen zeichnen
private void erhoeheFehler() {
fehler = fehler + 1;
gc.setLineWidth(4);
//je nach Wert von fehler zeichnen
switch (fehler) {
case 1:
gc.strokeLine(10, 10, 10, 200);
break;
case 2:
gc.strokeLine(10, 10, 100, 10);
break;
case 3:
gc.strokeLine(40, 10, 10, 40);
break;
case 4:
gc.strokeLine(100, 10, 100, 50);
break;
case 5:
gc.strokeLine(70, 50, 130, 50);
break;
case 6:
gc.strokeLine(130, 50, 130, 110);
break;
case 7:
gc.strokeLine(130, 110, 70, 110);
break;
case 8:
gc.strokeLine(70, 110, 70, 50);
break;
case 9:
gc.strokeLine(0, 200, 20, 200);
break;
}
}
}
Und hier noch die FXML Datei mit der UI:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.RowConstraints?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FXMLController">
<top>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Das gesuchte Wort" />
<Label text="Verbleibende Versuche:" GridPane.rowIndex="1" />
<Label fx:id="ausgabeText" GridPane.columnIndex="1" />
<Label fx:id="anzVersuche" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
</top>
<bottom>
<HBox prefHeight="41.0" prefWidth="600.0" spacing="150.0" BorderPane.alignment="CENTER">
<children>
<Label text="Ihre Auswahl:" />
<ComboBox fx:id="auswahl" onAction="#auswahlNeu" prefWidth="150.0" />
<Button mnemonicParsing="false" onAction="#beendenKlick" text="Beenden" />
</children>
</HBox>
</bottom>
<center>
<Canvas fx:id="zeichenflaeche" height="300.0" width="300.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Anfangs hatte ich das Problem den Controller mit der UI zu verbinden (mache das über den SceneBuilder Version 11.0.0).
Es hat erst geklappt als ich das Standardpaket in Java verwendet habe, spezifische Pakete konnte ich nicht erstellen.
Ich hoffe ich habe nicht zu verwirrend geschrieben. Da das hier mein erster Post ist, muss ich mich noch etwas einarbeiten.
Achja, hier noch die Fehlermeldung die angezeigt wird:
Code:
Exception in Application start 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:62)
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:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
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:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.IllegalAccessError: class com.sun.javafx.fxml.FXMLLoaderHelper (in unnamed module @0x19901c63) cannot access class com.sun.javafx.util.Utils (in module javafx.graphics) because module javafx.graphics does not export com.sun.javafx.util to unnamed module @0x19901c63
at com.sun.javafx.fxml.FXMLLoaderHelper.<clinit>(FXMLLoaderHelper.java:38)
at javafx.fxml.FXMLLoader.<clinit>(FXMLLoader.java:2056)
at HangmanFX.start(HangmanFX.java:11)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
... 1 more
Exception running application HangmanFX