FileManager - Ordner Vor / Zurück und Hoch - Buttons ?

hi,
ich wollte für einen FileManager einen zurück / vor und Hoch (also eine Ordnerebene nach oben) einbauen, zurück und vor kennt man z.B aus word einfach das letzte was man gemacht hat bzw eins weiter…
hier halt nur für ein ordner zurück navigieren bzw vor usw…
nun hab ich mir gedacht beim klick auf einen ordner wird der Pfad gleichzeitig an meine Klasse übergeben und in eine ArrayList eingesetzt, beim klick auf zurück wird der actionListener vom Button ausgelöst , in der Liste vom letzten element eins nach hinten gegangen, der Pfad genommen und in der anderen Klasse übergeben als Argument und der Ordnerwechsel durchgeführt, soweit so gut das klappt schonmal.

Aber das “vor” klappt noch nicht, er müsste vom aktuellen Pfad die Liste nach vorne gehen, aber wenn der user jetzt einen neuen Pfad zwischendrin anklickt, müssen die letzten in der Liste gelöscht werden und die neuen in die Liste gebracht werden, nur wie weiss man ob der user einen neuen Pfad wählt?
ausserdem geschieht das einsetzten des PFades in meine Liste bei jedem switchFOlder direkt in der Methode, allerdings glaube ich setze ich bei klick auf den zurück button den alten Pfad ein der wiederum auf die Methode switchFolder(name) zugreift, und dann wieder der Pfad in die Liste eingesetzt wird sozusagen. Also bräuchte ich 2 getrennte Methoden dafür?

Wie würdet ihr am besten einen vor/zurück button machen? und eine Ordnerebene hoch?

[QUOTE=Fred12]Wie würdet ihr am besten einen vor/zurück button machen? und eine Ordnerebene hoch?[/QUOTE]Also ich würde einfach den vorhandenen [JAPI]JFileChooser[/JAPI] benutzen…

bye
TT

Hallo Fred12,

deine Problembeschreibung ist verwirrend.

Am Besten, du setzt dich erst mal hin und definierst ganz genau, was welcher Button genau machen soll. Spiele die verschiedenen Möglichkeiten gedanklich durch. Finde durch Ausprobieren heraus, wie die Funktionen bei z. B. Word umgesetzt sind. Schmier dir ein paar Ablaufdiagramme oder ähnliches auf einem Stück Papier zusammen.
Und dann überlege dir, wie du das am besten programmiertechnisch umsetzen kannst.

MfG
hansmueller

@Timothy_Truckle
naja das ist aber nicht Sinn der Sache, oder hat ein FileChooser eingebaute vor / zurück buttons? es soll sich ja kein auswahlfenster öffnen sondern der nutzer soll einfach per klick vor/zurück navigieren können ;=)
@hansmueller hab ich ja schon, ich will einfach nur ein vor/weiter „Pfeil“ haben wie in Word der einfach nur das letzte ausführt was man gemacht hat bzw das hinterher :wink: nur übertragen auf die Ordnernavigation

JFileChooser stellt dem Benutzer einen Dateiauswahl-Dialog, in der für ihn gewohnten Optik (systemabhängig) zur Verfügung. Nicht mehr und nicht weniger.
Alles andere muss selbst gebaut werden.

Meinst Du Vor und Zurück Buttons wie z.B. im File Explorer von MS mit denen man einfach durch die Verzeichnisse springen kann die der Anwender mal ausgewählt hatte?
Oder eher ein Verhalten ähnlich dem wenn man im genannten Explorer mittels Cursor Tasten (rechts und links) in der Verzeichnishierarchie tiefer und höher wechselt?

@_Michael ja genau ich meine einfach wie im Windows Explorer wenn man irgendwo im ordnerverzeichnis ist, dann oben durch die Pfeiltasten vor und zurück springen kann :wink: am besten wär dann natürlich auch wenn die Pfeile enabled bzw disabled werden können wie in Windows wenn davor / dahinter keine navigation mehr ist…

so ein bisschen bin ich weitergekommen ich weiss aber selber nicht mehr genau wie das da funktioniert ;), nur der vor button stimmt so auch nicht so ganz, er hört nämlich gar nicht mehr auf zu springen auch wenn dahinter nichts mehr ist…

hier ist mein Code (eigentlich nur untere Abschnitt relevant):

        private String actualPath;
	private static ArrayList<String> pathList; 
	private String nowTempPath;

....................
....................
....................
....................



		//************************************************************************************************
		
		
		pathList = new ArrayList<String>();
		actualPath = sideFunctionsHelper.getFolder();
		addFolder(actualPath);
		
		
		
		

	}

	private ActionListener getNeuesFenster() {
		return new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null, TODO, "Neues Fenster",
						JOptionPane.OK_OPTION);

			}
		};
	}

	// public class ButtonListener implements ActionListener {

	@Override
	public void actionPerformed(ActionEvent ae) {

		Object quelle = ae.getSource();

		if (quelle == neuesFenster) {
			buttonBar.add(new JButton("GEKLICKT!"));

		}

		/**
		 * if (quelle == neuesFenster) { }
		 */

		if (quelle == zurueck) {
			//folderList.setSelectedIndex(folderList.getSelectedIndex()-1);			
			nowTempPath = getPreviousListElement(getLastListElement(actualPath));
			sideFunctionsHelper.switchFolder(nowTempPath);		
			
			//sideFunctionsHelper.getFolder();				
		}

		if (quelle == weiter) {
			sideFunctionsHelper.switchFolder(ButtonBar.getNextListElement(getActualElement(sideFunctionsHelper)));
		}

		if (quelle == hoch) {
		}

		if (quelle == home) {
			sideFunctionsHelper.switchFolder(System.getProperty("user.home"));
			//sideFunctionsHelper.getFolder();
		}

		if (quelle == aktualisieren) {
			sideFunctionsHelper.refresh();
		}

		if (quelle == favoritenAnlegen) {
		}

		if (quelle == favoritenAnzeigen) {
		}

		if (quelle == benutzer) {
		}

		if (quelle == ftpVerwalten) {
			FunctionsHelper.showOptions(1);

		}

		if (quelle == ftpAnzeigen) {
		}

		if (quelle == shellOeffnen) {
		}

		if (quelle == hilfe) {
			FunctionsHelper.showAbout();
		}

		if (quelle == einstellungen) {
		}		
				
	}
	
	
	//*****************************************************************************************************************
			//Funktionen für die ButtonNavigation , erstmal noch nicht in eigener Klasse
	

	public static void addFolder(String folderName) {	
//		if (pathList.contains(folderName))
//		{			
//		}
//		else {
			pathList.add(folderName);
				for (String element : pathList) {
					System.out.println(element);
			}		
		}
//	}
	
	public static String getActualElement(SideFunctionsHelper sideFunctionsHelper) {
		String actualPath = sideFunctionsHelper.getFolder();
		return actualPath;
	}
	
	public static String getPreviousListElement(String actualPath) {
		if (pathList.contains(actualPath)) {
			int index = pathList.indexOf(actualPath);
			String previousElement = pathList.get(index -1);
			//System.out.println(previousElement);			
			return previousElement;
		}
		return null ;
	}
	
	public static String getLastListElement(String actualPath) {
		if (!pathList.isEmpty()) {
			  String lastElement = pathList.get(pathList.size()-1);				  
			  return lastElement;			 
			}
		return null;			
	}
	
	public static String getNextListElement(String actualPath) {
		if (pathList.contains(actualPath)) {
			int index = pathList.indexOf(actualPath);
			/*if (index == pathList.size() -1) {
				return null;
			}*/
			
			String nextElement = pathList.get(index +1);				
			return nextElement;			
		}
		return null;				
	}
}

Dann brauchst Du eigentlich nur eine List und eine Indexvariable. Jedesmal wenn der Anwender in ein Verzeichnis navigiert, steckst Du das in die List. Wenn die List leer ist sind beide Buttons disabled. Steht der Index auf 0 ist der Zurück Button disabled steht der Index auf dem letzten Listenelement ist der Vorwärts Button disabled. Beim Navigieren mit den Buttons erhöhst Du bzw. reduzierst Du einfach den Index und zeigst das unter diesem Index referenzierte Verzeichnis aus der List an.

ok das klingt gut, aber was ist wenn ich jetzt zurück navigiere, (z.B 5 Elemente drin und ich geh auf index 2) und ab dem Punkt in einen neuen Zweig navigiere, muss ich dann alle Einträge danach in der Liste löschen? und ab dem Index 2 neu einfügen?

im prinzip ist vor und zurueck von dir ja nichts anderes als rueckgaengig und wiederherstellen in anderen Programmen.

also das zuruekc laesst sich am einfachsten mit einem Stack implementieren. fuer jeden ordner den der user auswaehlt wird eine eintrag auf den stack gelegt. sollte der user nun wieder mit dem zurueck button in den vorherigen Ordner wechseln wollen, wird einfach der oberste Eintrag vom stack genommen, und dieser wird angezeigt.

Nun noch das vorwaerts. dies ist immer nur vorhanden, wenn der user zuvor zurueck geklickt hat, das heiset du kannst wieder einen Stack nutzen. jedes mal wenn der User auf zurueck klickt, wird der aktuelle ordner (also der bevor du wohin navigierst) auf den zweiten Stack gelegt. Wenn der user wieder vor klickt nimmst du den ersten Eintrag des stacks wieder herunter und zeigst ihn an. Falls der user einen neuen Ordner auswaehlt, wird der zweite Stack wieder geleert.

Ich hoffe du meinst soetwas

Edit weil ziwschenzeitlich Michael geantwortet hat

Ich wuerde keinen List nehmen da der Stack dir hier viele arbeiten ab nimmt

also das zuruekc laesst sich am einfachsten mit einem Stack implementieren. fuer jeden ordner den der user auswaehlt wird eine eintrag auf den stack gelegt. sollte der user nun wieder mit dem zurueck button in den vorherigen Ordner wechseln wollen, wird einfach der oberste Eintrag vom stack genommen, und dieser wird angezeigt.

das kann nicht sein, denn der oberste eintrag wäre dann ja der aktuelle, und er soll ja einen zurück , also den eins darunter…

ja aber im Prinzip versteh ich was du meinst. Das schaut schon gut aus ich denke so lässt es sich machen :slight_smile: Nur wie groß soll ich den Stack 1 machen? Bzw in wieviele Unterordner kann man so etwa navigieren? Stack mit Größe 100 sollte schon reichen oder?

[QUOTE=Fred12]das kann nicht sein, denn der oberste eintrag wäre dann ja der aktuelle, und er soll ja einen zurück , also den eins darunter…
[/QUOTE]
haengt nur davon ab, wann du den aktellen Ordner auf den Stack legst, wenn du ihn immer beim Verlassen drauf legst sollte es passen.

[QUOTE=Fred12;63915] Nur wie groß soll ich den Stack 1 machen? Bzw in wieviele Unterordner kann man so etwa navigieren? Stack mit Größe 100 sollte schon reichen oder?
[/QUOTE]

Gar nicht. Verwende einfach den java.util.Stack der hat keine maximale Groesze

hm hab ich da irgendwo ein Logikfehler drin? er navigiert zwar zurück und vor , doch wenn ich paarmal auf zurück und wieder vor geht er nicht mehr ganz bis zum root zurück sondern immer 1 davor und bleibt dann stehen… irgendwo ein push/pop zuviel?



		stack1 = new Stack<String>();   //Stack für das Adden von Foldern
		stack2 = new Stack<String>();	//Stack für die Weiter-Button Logik

..................................
..................................
.................................

	public void actionPerformed(ActionEvent ae) {

		Object quelle = ae.getSource();	

		if (quelle == zurueck) {
			isSet= true;
			if (!stack1.isEmpty()) {
				String now = stack1.pop();
				stack2.push(now);
				String before = stack1.peek();
				if (stack1.size() == 1) {
					stack1.pop();
				}
				sideFunctionsHelper.switchFolder(before);	
				//stack2.push(before);				
				//weiter.setEnabled(true);
//				if (stack1.isEmpty()) {
//					zurueck.setEnabled(false);
//				}
//				weiter.setEnabled(true);
			}
					
		}

		if (quelle == weiter) {		
			isSet = true;
			if (!stack2.isEmpty()) {
				String now = stack2.pop();
				stack1.push(now);
				//String before = stack2.peek();
				sideFunctionsHelper.switchFolder(now);
				//stack1.push(before);
				
//				if (stack2.isEmpty()) {
//					weiter.setEnabled(false);
//				}
//			zurueck.setEnabled(true);
			}			
		}
		
	...........................
...................................
...................................

	public static void addFolder(String folderName) {	
		ButtonBar.getMarker();
		stack1.push(folderName);		
		stack2.removeAllElements();		
	}

		public static boolean getMarker() {
			System.out.println(isSet);
			return isSet;
		}
		
	}

also bitte stack1 (z.B. history) und stack2( forward) auf sprechende namen aendern das wuerde die lesbarkeit erhoehen.
und diese if-Bedingung verstehe ich nicht

   stack1.pop();
}```

Warum 2 Stacks wenn das genausogut mit einer Liste geht? Eine ArrayList und ein Index-Cursor für die aktuelle Position, man muss sich nur darum kümmern, dass wenn man x mal zurück geht und dann 1x vor, dass die x-1 Einträge danach gelöscht werden.

Und genau aus dieser Ueberlegung heraus finde ich STacks angenehmer, da ich dann nur den vorward Stack leeren muss.

Bei 2 stacks musst du bei jedem vor/zurück herum pushen/poppen. Das vorward stack leeren ist genauso aufwändig wie die Elemente nach Cursorposition zu löschen.

ja es war ein bisschen rumgefriemel , aber am Ende hats dann funktioniert :slight_smile: