OOP Vokabel-Trainer

OasisCritter

Bekanntes Mitglied
Hallo,

ich studiere seit einem Semester Informatik ohne Programmier-Vorkentnisse. Jetzt hab ich privat ein kleines Projekt gestartet wie der Titel schon sagt und bin schnell an meine Grenzen gestoßen, da ich noch nie ein vollständiges Java Programm geschrieben habe. Ich würde ja hier den Quellcode posten aber die Probleme sind sehr Klassenübergreifend und deshalb hab ich das gesamte Projekt als zip unten zum Download bereit.

1.Problem:
in "VFrame" wenn ich auf den JMenuItem "Wörter Hinzufügen" klicke, soll das bisherige "vpanel" durch ein "AddVokPanel" ersetzt werden.
Dazu benutze ich erstmal die "clearFrame()" Methode die irgendwie nicht funktioniert, da sich die Panels hinterher überlappen.

2.Problem:
In "AddVokPanel" ist es im Konstruktor schon kommentiert, ich will nähmlich das einlesen der beiden Sprachen über die Tastatur mit Hilfe eines Dialogs erwingen. Funktioniert nur teilweise oder garnicht, ich glaub er versucht es über die Console einzulesen.
Ich hab zwar eine Bibliothek "acm" die das einlesen über Dialog unterstützt allerdings kann ich von ihr nicht mehr erben, da ich schon von "Panel" erbe.

3.Problem:
In "VPanel" Zeile 69 steht das Problem geschildert.

Da ist glaub ich noch ein Makel aber fällt mir grad nicht ein.^^ Danke im Vorraus :toll:





Gruß OC
 

OasisCritter

Bekanntes Mitglied
Zu Problem 1: Also wenn ich auf Wörter Hinzufügen klicke, ändert sich das Panel nicht, erst durch vergrößern oder verkleinern des Fensters, selbst wenn ich repaint(); aufrufe wird erstmal das panel leer angezeigt und wiederum beim verändern der Fenstergröße das Panel richtig dargestellt.

Weis wirklich keiner weiter? Ich kann auch den Quellcode hier posten, das wird aber dann ein langer Beitrag.

Hab den Actionlistener von "Wörter Hinzufügen" geändert:

Java:
					clearFrame();
					vpanel= createAddVokPanel();
					frame.add(vpanel, BorderLayout.CENTER);
					vpanel.setVisible(true);
					frame.repaint();

Ich versteh das nicht, in dem Moment wo ich sage "vpanel= createAddVokPanel();" zeigt der Zeiger doch auf "AddVokPanel" Trotzdem wirds durch repaint nicht angezeigt.

Wichtig: Was ich vergessen hab zu erwähnen, in VFrame ist die Main-Methode zum Testen.


MfG
 
Zuletzt bearbeitet:

Marcel_Handball

Bekanntes Mitglied
Hey,

ich habe mir deinen Quellcode nicht angeschaut, aber wenn ich dich richtig verstanden habe, könntest du das CardLayout benutzen, um die Panels "zu ersetzen".

ich will nähmlich das einlesen der beiden Sprachen über die Tastatur mit Hilfe eines Dialogs erzwingen

Wie genau stellst du dir das vor. Vll hilft dir die Klassen JOptionPane weiter.
 

OasisCritter

Bekanntes Mitglied

eRaaaa

Top Contributor
Also beim "JFileChooser.showSaveDialog" da bekomm ich immer eine NullPointer oder auch mal was anderes.

Jepp liegt daran dass du im Konstruktor
Code:
setFrameContents();
VOR
Code:
FChooser = new JFileChooser();
aufrufst...

Zeilen tauschen könnte zumindest die Exception beheben, die Frage ist allerdings, wieso das
Code:
FChooser.showSaveDialog(card2);
überhaupt innerhalb von
Code:
setFrameContents()
aufgerufen wird? So wird ja sobald VFrame instanziiert wird, direkt der FileChooser aufgerufen. Sollte das nicht viel eher erst dann aufgerufen werden, wenn man auch im Menü auf "Speichern" klickt? :D Also müsste das womöglich in irgendeinen Listener...
 

OasisCritter

Bekanntes Mitglied
Ja^^ thx, hab den ActionListener vergessen.

Bei der Funktion im AddVokPanel:
Java:
/*Wörter Speichern==============================================*/
		// (unsauber aber es reicht)
		save.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				
             Component[] cont = getComponents();
             StringBuffer sb = new StringBuffer();
             sb.append("Die Vokabeln: ");
             int j=1;
             for(int i=2;i<12;i+=2) {
            	 JTextField first =  (JTextField)cont[i];
            	 JTextField second =  (JTextField)cont[i+1];
            	 String firstText =first.getText();
            	 String secondText = second.getText();
            	// System.out.println(firstText+ " " + secondText);
				if(firstText != null && secondText != null) {
					vokbox.add(new Vokabel(firstText, secondText, 0));
					first.setText(null);
					second.setText(null);
					sb.append(j).append(" ");
				}	
				j++;
             }
             sb.append("wurden hinzugefügt!");
             //Message
             dumpToDialog(sb.toString());
			}
		});

speichert er alle Felder als Vokabel obwohl die TextFelder leer sind, also Funktioniert die if-Bedingung nicht. Weder mit "null" noch mit einfachen "". Das wird auch dadruch klar, dass er mit der variablen j, alle Felder zählt. Wenn ich den Inhalt der leeren Textfelder auf der Console ausgeben lasse wird nix angezeigt, bin ratlos.

MfG
 
Zuletzt bearbeitet:

eRaaaa

Top Contributor
naja null sind sie ja auch nicht...Wie hast du den test mit einfachen "" gemacht? Mit equals? Oder etwa mit == "" ? Ansonsten probiere doch mal die Methode
Code:
isEmpty()
->
Java:
 if(!firstText.isEmpty() && !secondText.isEmpty())
 

OasisCritter

Bekanntes Mitglied
Jo, funkt super :toll:.
Das speichern und einlesen hat auch gut funktioniert. Jetzt hab ich versucht am Anfang der File jeweils die beiden Languages zu schreiben, also so:

language1 language2
Vokname1 Vokantwort1 0
Vokname2 Vokantwort2 0

Es funktioniert auch, nur beim einlesen, sieht er die erste Vokabel als Sprachen, also er überspringt im Prinzip die erste Line.

Ich glaub das liegt an FileInput: Line 92. Kannst du viell nochma drüberschauen? :bahnhof:

PS: Das speichern erfolgt in einer beliebigen File mit der Endung ".lek", später versuch ich das noch zu erzwingen.

Aktuelles Projekt:
VokTrain.rar ... at uploaded.to - Free File Hosting, Free Image Hosting, Free Music Hosting, Free Video Hosting, ...


MfG
 

eRaaaa

Top Contributor
Also das verstehe ich jetzt nicht :D Was hast du genau vor?
Das speichern und einlesen hat auch gut funktioniert. Jetzt hab ich versucht am Anfang der File jeweils die beiden Languages zu schreiben, also so:
In der .lek-Datei im Archive steht das aber nicht so?

Es funktioniert auch, nur beim einlesen, sieht er die erste Vokabel als Sprachen, also er überspringt im Prinzip die erste Line.
?! Erste Linie ist doch denke ich jetzt die Sprache?

(vllt habe ich dich auch falsch verstanden, dann erkläre es bitte noch einmal)
Das Einlesne sieht auch irgendwie total kompliziert aus, mit dem Scanner geht das sicherlich etwas leichter
Also, wenn die Datei jetzt beispielsweise so aussieht
Code:
Deutsch Englisch
hallo hello 0
throw werfen 0
say sagen 0

könnte deine parseFile vllt so aussehen
Java:
    private void parseFile(Reader reader) throws IOException {
	scanner = new Scanner(reader);
	String[] line1 = scanner.nextLine().split(" ");
	language1 = line1[0];
	language2 = line1[1];
	while (scanner.hasNextLine()) {
	    String[] line = scanner.nextLine().split(" ");
	    vokbox.add(new Vokabel(line[0], line[1], Integer.parseInt(line[2])));
	}
    }
In language1 und language 2 steht dann Deutsch & Englisch und in vokbox sind eben die 3 Vokabeln...so war das doch gedacht oder? :oops:
 

OasisCritter

Bekanntes Mitglied
So wars gemeint, habs jetzt auch mit meiner Variante hinbekommen^^. Trotzdem danke, das mit dem Scanner sieht ja nice aus :D

Kurze Frage nebenbei, wenn man eine Statusanzeige im Panel, z.B. ein optischen Timer (hat jetzt nix mit der Timer Klasse zutun) oder in meinem Fall eine Anzeige, die zeigt wieviele Wörter bereits gelernt worden sind, wie mach ich das am besten? Über ein JLabel das immer wieder den Text ändert ist glaub ich nicht so gut. Die Anzeige soll im VPanel platziert werden, dafür ist extra oben noch platz.


MfG
 

eRaaaa

Top Contributor
Über ein JLabel das immer wieder den Text ändert ist glaub ich nicht so gut.

Och wieso?

Ansonsten halt vllt eine ProgressBar
jprogressbar.gif
(JProgressBar)(How to Use Progress Bars)

Oder du lädst verschiedene Images die den Status abbilden, zeigst den Fortschritt in Form eines Tortendiagramms oder oder ...lass dir was kreatives einfallen *g*
 

OasisCritter

Bekanntes Mitglied
Beim exportieren des Projektes konnte ich anfangs durch "next" auswählen welche Dateien in die Jar-File exportiert werden sollen. Jetzt hab ich das Projekt abgeändert und mit 2 Bildern versehen, die allerdings nicht mehr in die Jar exportiert werden oder der path wird geändert sodass er die Bilder nicht mehr findet.
Beim path sag ich immer "../Projekt/../../Bild". Beim compilieren in Eclipse werden die Bilder ja angezeigt, wie soll ich den Path denn aufgaben?

Und ist die runnable-Jar-File die einzige Möglichkeit eine Java-Programm zu erstellen? Ich weis es gibt noch bestimmte Tools die daraus eine .exe machen aber das mein ich nicht, sondern speziell beim Exportieren in Eclipse.

Warum kann man eigentlich eine Jar-File erstellen die sich nicht ausführen lässt und das auch noch als Standard-Option?

Ach und wie kann man der .jar ein Icon anhängen?^^

MfG
 
Zuletzt bearbeitet:

OasisCritter

Bekanntes Mitglied
FileInput:
Java:
private void parseFile(Reader reader) throws IOException {
    StreamTokenizer stok = new StreamTokenizer(reader);
	stok.eolIsSignificant(true);
	stok.quoteChar('\"');
	
	int token = 0;
	String abfrage = null;
	String antwort = null;
	int geloest =0;
	 // read languages
	    token = stok.nextToken();
		language1 = (String)stok.sval;
		token = stok.nextToken();
		language2 = (String)stok.sval;
		token = stok.nextToken(); // EOL
	
	// read Vokabel Objects
	while((token = stok.nextToken()) != StreamTokenizer.TT_EOF) {
		abfrage = (String)stok.sval; // 1.Token
		token = stok.nextToken();
		antwort = (String)stok.sval; // 2.Token
		token = stok.nextToken();
		geloest = (int)stok.nval;    //3.Token
		token = stok.nextToken();  // EOL
		
		vokbox.add(new Vokabel(abfrage, antwort, geloest));
	}
	}

FileOutput:
Java:
public void writeVokToFile() throws IOException {
		BWriter = new BufferedWriter(new FileWriter(SFile));
		
		BWriter.append(language1).append(" ").append(language2);
		
		for(int i=0;i<vokbox.size();i++) {
			BWriter.newLine();
			Vokabel current = vokbox.get(i);
			Integer geloest = (Integer)current.getGeloest();
			BWriter.append('"').append(current.getAbfrage()).append('"').append(" ").
			append('"').append(current.getAntwort()).append('"').append(" ").
			append(geloest.toString());
		}
		
		BWriter.flush();
		BWriter.close();
	}
 

eRaaaa

Top Contributor
.....
Java:
BWriter = new BufferedWriter(new FileWriter(SFile));

wo ist SFile definiert? Das ist ja gerade der PFAD + das was uns interessiert ;D !!!
 

OasisCritter

Bekanntes Mitglied
Fileoutput:

File:
Java:
File SFile;
Konstruktor:
Java:
public FileOutput(String Filename) {
		SFile = new File(Filename);
		vokbox = new ArrayList<Vokabel>();
	}

Und der Save-Button:
Java:
save.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent e) {
			
				if(parentControl.getVokbox() == null || parentControl.getVokbox().isEmpty()) {
					dumpToDialog("Die Datenbank ist leer!");
					return;
				} else if(language1 == null || language2 == null) {
					JOptionPane.showMessageDialog(window, "Sie müssen die Sprachen festlegen, bevor sie fortfahren.");
					return;
				} 
				
				int returnVal= FChooser.showSaveDialog(card2);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = FChooser.getSelectedFile();
		            FileOutput FOutput = new FileOutput(file);
		            FOutput.setVokbox(vokbox);
		            FOutput.setLanguage1(language1);
		            FOutput.setLanguage2(language2);
		            try {
						FOutput.writeVokToFile();  // write vokbox to file
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				
			}
		});
 

eRaaaa

Top Contributor
Ähh..du suchst dir ja anscheinend die Datei selbst raus mit dem FileChooser?! Ist jetzt deine Frage also, wie du im FileChooser nur .lek Dateien auswählen kannst oder wie?

dann irgendwie so vllt:
Java:
	FChooser.setFileFilter(new FileFilter() {
	    @Override
	    public String getDescription() {
		return "Vokabel-Datei";
	    }

	    @Override
	    public boolean accept(File f) {
		return f.isDirectory()
			|| (f.isFile() && f.getName().endsWith(".lek"));
	    }
	});
[/Java]

Du kannst ja evtl. auch schon einen Dateinamen direkt vorgeben....
[code=Java]
FChooser.setSelectedFile(new File("vok.lek"));

Dennoch kann man natürlich immer noch in dem Textfeld eingeben was man will, wenn du das nicht willst, musst du das halt nach
Java:
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File file = FChooser.getSelectedFile();

selbst überprüfen. z.b.
if(!file.getName().endsWith(".lek")){
//fehler...
}

...
 

OasisCritter

Bekanntes Mitglied
Wie ich das jetzt verstanden habe, wird bei deinem obersten Code, die Dateiendung erzwungen, also selbst wenn man irgendetwas eingibt, wird es vom FileChooser nicht akzeptiert. Dann muss man doch nicht noch selbst überprüfen obs tatsächlich eine .lek datei ist, oder?
 

eRaaaa

Top Contributor
Wie ich das jetzt verstanden habe, wird bei deinem obersten Code, die Dateiendung erzwungen, also selbst wenn man irgendetwas eingibt, wird es vom FileChooser nicht akzeptiert. Dann muss man doch nicht noch selbst überprüfen obs tatsächlich eine .lek datei ist, oder?

Doch musst du denke ich schon. Der obere Code ist nur für die Ansicht....er zeigt so halt nur Ordner + .lek-Files an. Man könnte jetzt dennoch ins Textfeld vok.txt schreiben wenn man will..kannst es ja mal ausprobieren ;D
 

OasisCritter

Bekanntes Mitglied
Du hattest recht, er nimmt die Datei mit falscher Endung trotzdem an. Hab das Problem jetzt so gelöst:

Öffnen der Datei:
Java:
 if(VokFile.isFile() && !VokFile.getName().endsWith(".lek")) {
		        	dumpToDialog("Die Datei hat das falsche Format! \n Vergewissern sie sich, dass sie eine Datei mit der Endung \" .lek \" ausgewählt haben.");
		        	return;
		        }

Beim speichern:
Java:
int returnVal= FChooser.showSaveDialog(card2);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            File file = FChooser.getSelectedFile();
		            
		            FileOutput FOutput = new FileOutput(file.getPath()+ ".lek");

Dadurch wird der Datei immer die Endung ".lek" gegeben, egal was der user hintendran gestellt hat :D
 
Zuletzt bearbeitet:

OasisCritter

Bekanntes Mitglied
Gibts es eine Möglichkeit einem JMenuItem, ein oder mehrere weitere JMenuItems anzuhängen, also so, das ein Untermenü ensteht?

menuitem48313d01JPG.jpg


Da wo der rote Pfeil ist, soll ein Untermenü enstehn.
 

OasisCritter

Bekanntes Mitglied
Ich hab ein seltsames Problem bei der Abfrage der Vokabeln. Also...ich habe den Vokabeltrainer um eine VokabelART namens "Hybrid" erweitert, welche bis zu 3 Bedeutungen für die jeweiligen Sprachen haben kann. Bevor ich die Erweiterung gemacht habe, hat das Abfragen der Vokabeln sehr gut funktioniert. Jetzt nach dem erweitern, funktioniert die Abfrage der Hybride gut, nur bei den Vokabeln gibt es Probleme.

Das Problem:
Wenn man versucht alles richtig auszufüllen, wird bei der 3ten Vokabel (ich weis nicht obs immer bei der dritten ist) keine neue Vokabel angezeigt und wenn man dann auf weiter klickt, wird das als Falsch gezählt.
===================================

Dieser Button regelt die Abfrage:
Java:
private JButton getNextButton() {
		if(next == null) {
			next = new JButton("Weiter");
			/*Weiter (next Vokabel)=============================================*/
			next.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent arg0) {
					if(startStatus) {
						if(parentWindow.parentControl.VokboxIsEmpty()) {
							parentWindow.dumpToDialog("Es befinden sich keine Vokabeln in der Datenbank");
						   return;
						}
					
					// if answer-field is empty (überspringen)
					if(getRightVok().getText().isEmpty() || getRightVok().getText() == null) {
						// System.out.println("Übersprungen");
						setBoolPic("swap");
						rightVok.setText(null);
						// set and show next Vokabel
		                SetAndShowNextVokabel();
		                return;
					}
					
					//Answer
					String answer_full = getRightVok().getText();
					String answer_low = getRightVok().getText().toLowerCase();
					// if answer was right (match) ** HYBRID **
					if(currentVok instanceof Hybrid) {
						Hybrid vok = (Hybrid)currentVok;
						if(answer_low.equals(vok.getAntwort().toLowerCase()) || answer_low.equals(vok.getAntwort2().toLowerCase()) || answer_low.equals(vok.getAntwort3().toLowerCase())){
							setBoolPic("right");
							currentVok.setGeloest(currentVok.getGeloest()+1); // count geloest + 1
							
							if(currentVok.getGeloest() >= 3) {
							      //remove Vokabel from vokbox
							      parentWindow.parentControl.removeVok();
						
						          // refresh progressBar
						          progress++;
						          refreshProgressBar();
						      }
					} else { // if answer was WRONG HYBRID
						setBoolPic("wrong");
						if(currentVok.getGeloest() > 0) {
						currentVok.setGeloest(currentVok.getGeloest()-1);
						// parentWindow.parentControl.refreshAVokToBox(currentVok, changedVok);
						}
					}   // if answer was right (match) ** VOKABEL **
					} else {
						
						if(answer_low.equals(currentVok.getAntwort().toLowerCase())){
						setBoolPic("right");
						currentVok.setGeloest(currentVok.getGeloest()+1); // count geloest + 1
					
						if(currentVok.getGeloest() >= 3) {
							      //remove Vokabel from vokbox
							      parentWindow.parentControl.removeVok();
						
						          // refresh progressBar
						          progress++;
						          refreshProgressBar();
						}
					} else { // if answer was WRONG VOKABEL
						setBoolPic("wrong");
						if(currentVok.getGeloest() > 0) {
						currentVok.setGeloest(currentVok.getGeloest()-1);
						// parentWindow.parentControl.refreshAVokToBox(currentVok, changedVok);
						}
					}
					}
					// clear input TextField
					rightVok.setText(null);
					
					if(parentWindow.parentControl.VokboxIsEmpty()) {
						parentWindow.dumpToDialog("Herzlichen Glückwunsch, sie haben die Lektion erfolgreich bestanden");
						next.setEnabled(false);
					   return;
					}
					// set and show next Vokabel
	                SetAndShowNextVokabel();
	                
					} else {
						// message
						parentWindow.dumpToDialog("Sie müssen vorher die Abfrage starten!");
					}
				}
			});
			next.setVisible(true);
		}
		return next;
	}

rightVok = das EingabeFeld für die Antwort!
currentVok = momentane Vokabel in der Abfrageklasse!
Klasse: Vokabel
Java:
String abfrage=null;
	String antwort=null;
	int geloest=0;
/**
	 * 
	 */
	public Vokabel(String abfrage, String antwort, int geloest) {
		this.abfrage = abfrage;
		this.antwort = antwort;
		this.geloest= geloest;
	}
Klasse: Hybrid
Java:
private String abfrage2 = null;
	private String abfrage3 = null;
	private String antwort2 = null;
	private String antwort3 = null;
/**
*
**/
public Hybrid(String abfrage, String abfrage2, String abfrage3, String antwort, String antwort2, String antwort3, int geloest) {
    super(abfrage, antwort, geloest);
    this.abfrage2 = abfrage2;
    this.abfrage3 = abfrage3;
    this.antwort2 = antwort2;
    this.antwort3 = antwort3;
	}

Die Methode: toggleVok()
Java:
/**
	 * Changes the currentVok in VPanel
	 */
	public void toggleVok() {
	
      Random random = new Random();
		RNumber = random.nextInt(vokbox.size());
		  // if vokbox size >1, dont show the same Vokabel 2 times
		if(vokbox.get(RNumber).equals(window.card1.getCurrentVok()) && vokbox.size() >1)
		toggleVok(); 
		else {
		window.card1.setCurrentVok(vokbox.get(RNumber));
		}
	}

Hier eine ausfürhbare Version mit TestLektion:
VokTrainer.rar ... at uploaded.to - Free File Hosting, Free Image Hosting, Free Music Hosting, Free Video Hosting, ...

Wenn du mehr Code sehn willst, sagt bescheid.

MfG
 

OasisCritter

Bekanntes Mitglied
Ich hab den Bug jetzt gefunden und behoben. Es lag an einer Switch-Anweisung bei der manchmal kein passendes Case gefunden wurde. :D

Ich will jetzt versuchen, ein Menüeintrag zu erstellen, durch den nach neuen Updates gesucht werden soll. Ich hab eine Domain + Webspace und eine Web-SQL-DB. Allerdings weis ich nicht so richtig wie ich das machen soll.:bahnhof: Kennst du viell. eine Musterlösung (bzw. Musterbeispiel) für sowas?

thx
 

eRaaaa

Top Contributor
Also ich würde dir raten ein neues Thema auf zumachen und dort deine Frage zu stellen, denn die schweift ja jetzt doch sehr stark vom eigentlichen Vokabel-Trainer ab und ist ja eine sehr allgemeine Frage. Zudem schauen hier wohl nur noch die Wenigsten rein bei so langen Themen.
 

OasisCritter

Bekanntes Mitglied
Wie greift man am besten auf eine interne Datei zu?

Nehmen wir mal an, die Datei heißt "config.dat" und ist im Package "files".

mit
Code:
getClass().getResource("/files/config.dat");
bekommt man eine URL. Und wenn ich es so versuche:

Java:
URL fileurl = getClass().getResource("/files/config.dat");
	
File configFile = new File(fileurl.getPath());

findet er die Datei nicht.
 
T

Tomate_Salat

Gast
[c]getClass().getClassLoader().getRessource("files/config.dat");[/c]

könnte klappen, aber du könntest das ganze auch gleich als InputStream öffnen :-/ [c]...getRessourceAsStream("files/config.dat")[/c]
 

OasisCritter

Bekanntes Mitglied
[c]getClass().getClassLoader().getRessource("files/config.dat");[/c]

könnte klappen, aber du könntest das ganze auch gleich als InputStream öffnen :-/ [c]...getRessourceAsStream("files/config.dat")[/c]

Ne, klappt beides nicht:

...\JavaWorkspace\Vokabel\bin\files\config.dat (Das System kann den angegebenen Pfad nicht finden)

Viell. liegt es am "\bin\" , weiß auch nicht warum es da steht.
 

eRaaaa

Top Contributor
Wahhh, es ist zu spät :autsch:

- in welchem Package befindet sich überhaupt die aufrufende Klasse?
- was hast du damit dann vor?
 
Zuletzt bearbeitet:

OasisCritter

Bekanntes Mitglied
Du meinst so:

Java:
URL fileurl = getClass().getClassLoader().getResource("files/config.dat");
File configFile = new File(fileurl.toURI());

oder so:

Java:
URL fileurl = getClass().getResource("/files/config.dat");
File configFile = new File(fileurl.toURI());

Beides läuft aufs gleiche hinaus, und in Eclipse funktioniert es wunderbar. Nur Außerhalb nicht.

...
 

mvitz

Top Contributor
Was genau meinst du mit "außerhalb"? Versuchst du das ganze nur über die Konsole zu starten oder hast du ein JAR gebaut? Wenn du ein JAR gebaut hast, wie hast du das gemacht?
 

mvitz

Top Contributor
Nächste Frage:
Ist dein Ordner: "files" ein Source Folder? Wenn nicht, dann Rechtsklick auf "files" --> "Build Path" --> "Use as source folder" und anschließend erneut "Export as Runnable File".

(Ich nehme an du möchtest deine Configuration im JAR haben?)

Evtl. wäre auch ein Screenshot von deinem aufgeklapptem Eclipse Projekt hilfreich!
 

OasisCritter

Bekanntes Mitglied
Nächste Frage:
Ist dein Ordner: "files" ein Source Folder? Wenn nicht, dann Rechtsklick auf "files" --> "Build Path" --> "Use as source folder" und anschließend erneut "Export as Runnable File".

(Ich nehme an du möchtest deine Configuration im JAR haben?)

Evtl. wäre auch ein Screenshot von deinem aufgeklapptem Eclipse Projekt hilfreich!


Ja die "config.dat" soll mit in die JAR. Jetzt wo "files" ein Source Folder ist, gehts auch in Eclipse nicht mehr.

Hier Bild (bissl klein da netbook):

http://s2.imgimg.de/uploads/eclipseba932351JPG.jpg

Übrigens die Nullpointer ensteht nicht, wegen "configFile = null;" unten im Konstruktor wird die configFile entsprechend initialisiert.
...
 
Zuletzt bearbeitet:

mvitz

Top Contributor
Ok, der Ordner "files" lag schon unter "src" dann kannst du das mit dem eigenen Source-Folder wieder Rückgängig machen (selber weg wie vorher nur jetzt "Remove as source folder" oder so ähnlich).

Ich würde jetzt vorschlagen: Setze hinter dein
Java:
URL fileurl = getClass().getClassLoader().getResource("files/config.dat");

einfach mal ein
Java:
System.out.println(fileurl);

und starte das neu Exportierte Runnable jar einmal über die Konsole mit

Code:
java -jar DeinJarName.jar

Und dann sagst du uns, was da steht. Weiterhin könntest du noch überprüfen, ob es die Datei config.dat bis in dein JAR File hinein schafft, indem du das exportiere JAR File einmal mit Winzip oder Winrar oder ähnlichen öffnest.
 

OasisCritter

Bekanntes Mitglied
Also

1. Die "config.dat" befindet sich in der JAR

2. System.out.print(fileurl); == file:/C:/My%20Dropbox/Privat/JavaWorkspace/Vokabel/bin/file/config.dat

3. Wenn ich die jar mit der Konsole öffnen will, steht da "Unable to Access jarFile". Ich habs mit der Windows Konsole probiert, ich hoffe du meinst nicht die java-konsole.
Eine Frage dazu, woher weis die Konsole wo sich die Jar befindet, wenn ich nur den Namen angebe?

Edit: hier zur cmd: http://s2.imgimg.de/uploads/cmd0fcc2aeaJPG.jpg

Zeile 83:
Code:
configFile = new File(fileurl.toURI());
 
Zuletzt bearbeitet:

mvitz

Top Contributor
Dein Problem liegt daran, dass man kein File Objekt für ein File innerhalb des JARs bauen kann. Was genau willst du mit der config.dat machen? Nur lesen, dann benutze direkt getResourceAsStream(..) wodurch du einen InputStream zum auslesen bekommst. Wenn du in die Datei auch schreiben willst, kann es so gar nicht funktionieren.
 

OasisCritter

Bekanntes Mitglied
Dein Problem liegt daran, dass man kein File Objekt für ein File innerhalb des JARs bauen kann. Was genau willst du mit der config.dat machen? Nur lesen, dann benutze direkt getResourceAsStream(..) wodurch du einen InputStream zum auslesen bekommst. Wenn du in die Datei auch schreiben willst, kann es so gar nicht funktionieren.

Also, beim Start des Programms soll aus der Datei gelesen werden (settings). Beim Beenden des Programms werden die aktuellen settings wieder in die Datei geschrieben.
Wenn es so nicht funktionieren kann, wie dann? :bahnhof:

...
 
T

Tomate_Salat

Gast
da reicht ein relativer Pfad. z.B. einfach [c]new File("data.dat");[/c] sollte er die Datei ansprechen, welche im selben VZ liegt wie deine JAR (sofern du von dieser startest. Hast du z.B. einen exe-Loader oder glaub auch bat-Loader, dann sucht der im VZ des Loaders....halt eben dort wo der Programmaufruf statt gefunden hat)
 

mvitz

Top Contributor
Ansonsten, wenn es eine ausführbare JAR-Datei ist einfach ins Manifest:
Code:
Class-Path: .

Und dann wie gehabt über getClass().getClassloader().getResource(); und anschließend new File()
 

OasisCritter

Bekanntes Mitglied
hmm:(

Nachdem ich eine nicht genutzte externe Library aus dem BuildPath entfernt habe, funktioniert das Program wieder mal nur in Eclipse :autsch: Nachdem ich die Library wieder zum BuildPath hinzugefügt habe, hat sich das Problem gehalten.
Ich bekomme außerhalb von Eclipse (also in einer runnableJAR) eine NullPointerException bei folgendem code:

Java:
images = new HashMap<String, ImageIcon>();

images.put("right", new ImageIcon(getClass().getClassLoader().getResource("images/" + theme + "/right.png")));

so funktioniert es auch nicht:

Java:
images.put("right", new ImageIcon(getClass().getResource("/images/" + theme + "/right.png")));

exception24f700daPNG.png


Ich versteh das nicht, wie kann sowas einfach nicht mehr funktionieren :bahnhof:
 

nrg

Top Contributor
würd ich mal sagen, dass der pfad falsch ist. hast du denn den classpath in der manifest angepasst und das aktuelle verzeichnis ("Class-Path ." oder so) hinzugefügt? Ich würde prinzipiell beim Laden von Dateien mit classloader direkt die NPE catchen und eine anständige Fehlermeldung ausgeben. merkst ja jetzt selber, dass der Fehler recht blöd nachvollziehbar ist.
 

Ähnliche Java Themen

Neue Themen


Oben