Java JScrollPane in ein JFrame einfügen.

Zespire

Lieutenant
Registriert
März 2007
Beiträge
857
Grüße euch Alle,

ich habe vor 3 Wochen angefangen mit Programmieren und mich für Java entschieden.

Jetzt habe ich es endlich geschafft einen simplen Dungeon-Generator zu schreiben bei dem ich am Anfang alles in Textform ausgegeben habe Z.b # = Wand, 0 = Leere Fläche und so weiter.

Dann habe ich mir eine etwas schönere Lösung zusammen geschustert mit ImageIcons das Problem ist, ab einer bestimmten Dungeongröße passt der Dungeon nicht mehr in das JfFrame.

Nun stelle ich mich wirklich zu blöd an, dem Ganzen einen einfachen Scrollbalken zu veprassen und hoffe das ihr helfen könnt.

Hier der Code für die Ausgabe.

Code:
package dungeongenrator;


import java.awt.Dimension;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;



public class output {

	private static Icon[] bilder = { new ImageIcon("GFX/empty.png"),new ImageIcon("GFX/wand.png"), new ImageIcon("GFX/raum.png"), new ImageIcon("GFX/door.png"),new ImageIcon("GFX/1.png"),new ImageIcon("GFX/2.png"),new ImageIcon("GFX/3.png"),new ImageIcon("GFX/4.png")};;
	
	
	public static void main(String args[]) {
		output.fenster();
	
	}
	
	
	public static void fenster(){
		

		
		
		int map[][] [] = MAP.dungeon;
		short map_y = 300;
		short map_x = 300;
		int anzahl = map_y*map_x;
		short zeilen =  (short) (map_x-1);
		short spalten = (short) (map_y-1);
		int tile_x =0;
		int tile_y =0;
		

		

	// ################# Fenster wird erstellt #####################
	
		
	JFrame f = new JFrame();
	f.getContentPane().setPreferredSize(new Dimension(600, 600));
	f.pack();
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	f.setVisible(true);
	f.setResizable(true);
	f.setLayout(null);
	JLabel tile[] = new JLabel [anzahl];


	
	MAP.dungeon[0][0][0] = 1;
	
	anzahl--; // ??????????
	
		



	
	
	//########################## Raum wird gezeichnet ########################## 
	
	while(zeilen>=0){
		
		

		while(spalten>=0){
			
	if(map[zeilen][spalten][0]==0){tile[anzahl] = new JLabel (bilder[0]);} //empty
	if(map[zeilen][spalten][0]==1){tile[anzahl] = new JLabel (bilder[1]);} //wand
	if(map[zeilen][spalten][0]==3){tile[anzahl] = new JLabel (bilder[2]);} //raum
	if(map[zeilen][spalten][0]==4){tile[anzahl] = new JLabel (bilder[3]);} //tür
	if(map[zeilen][spalten][0]==11){tile[anzahl] = new JLabel (bilder[4]);} //test1
	if(map[zeilen][spalten][0]==12){tile[anzahl] = new JLabel (bilder[5]);} //test2
	if(map[zeilen][spalten][0]==13){tile[anzahl] = new JLabel (bilder[6]);} //test3
	if(map[zeilen][spalten][0]==14){tile[anzahl] = new JLabel (bilder[7]);} //test4
	
	tile[anzahl].setBounds(tile_x,tile_y,2,2);
	f.add(tile[anzahl]);
	tile_x=tile_x+2;
	anzahl--;
	spalten--;
		}
		
		
		
		tile_x=0;
		tile_y =tile_y+2;
		spalten = (short) (map_y-1);
		zeilen --;
		
	}
	
	
	f.repaint();

		}

}

Hier ist das Ergebnis des Generators.

 
Zuletzt bearbeitet:
Du brauchst diese Hierarchie: JFrame->JScrollPane->Component
Auf das Component (kann z.B. ein JPanel sein) packst du dann deine Labels drauf.

Btw. sollte setVisible() erst zum Schluss aufgerufen werden und pack() afaik ebenso, sonst hat das keinen Effekt.
 
Also wen ich das richtig verstehe, füge ich meinem JFrame ein JScrollPanel hinzu, in das JScrollPanel stecke ich dann ein JPanel und auf dem JPanel zeichne ich dann meine Icons.

[edit:] Da stellt sich mir gleich eine wichtige Frage, soll ich dann die größe des JPanel immer anpassen oder merkt Java von alleine das die Icons die Bounds des JPanel verlassen.
 
Zuletzt bearbeitet:
Einfach mal testen. ;)
Ich bin nicht sicher, ob es mit dem Null-Layout funktioniert. Wenn nicht, musst dem JPanel explizit eine Größe zuweisen.
 
Danke für die Hilfe hat mich auf die richtige Spur gebracht.

Hatte es in die Richtung schon probiert aber es wollte mir nicht gelingen.
Das lag zum einen daran das ich das Scrollpane in das JPanel gesteckt habe und zum anderen bin ich nicht auf die Idee gekommen dem JPanel eine PreffredSize zu geben.

Code:
	JFrame f = new JFrame();
	f.getContentPane().setPreferredSize(new Dimension(600, 600));
	f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	f.setResizable(false);
	f.setLayout(null);
	
	JLabel tile[] = new JLabel [anzahl];

	JPanel jp = new JPanel(null);
	jp.setBounds(0, 0, 2000, 2000);
	jp.setPreferredSize(new Dimension(2000, 2000));
	jp.setBackground(Color.black);
	JScrollPane sp = new JScrollPane(jp,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
	sp.setBounds(0, 0, 600, 600);

	
	f.add(sp);
	f.pack();
	f.setVisible(true);

Läuft jetzt so wie es soll.
 
du kannst auch eine eigene Klasse erstellen, die von JPanel erbt und bei dem Konstruktor dann die Bilder hinzufügen
dann hättest du das Ganze Objektorientiert gelöst
zB
Code:
public class DungeonMap extends JPanel {
/**
 * Konstuktor
 */
      public DungeonMap() {
      //hier Code einfügen
      }

}

hätte den Vorteil, dass du schnell (auch verschiedene) Maps erstellen kannst
auch ist das Erweitern dann teilweise einfacher
 
Danke für den Hinweis bin gerade dabei etwas in der Richtung zu schreiben, das werde ich dann gleich mit einem KeyListener verbinden hier mal der aktuelle Stand.

Code:
public class Window extends JFrame {
	private Screen  screen;

	
	
	public Window(){
		super("test");
		screen = new Screen();
		screen.setBounds(0, 0, 800, 600);
		add(screen);
		
		
	}
	
	public void RepaintScreen(){
		
		screen.repaint();
		
	}
	
	
	private class Screen extends JLabel{
		
		protected void paintComponent(Graphics arg0) {

			
			super.paintComponent(arg0);
		}
		
		
	}
	
}


Im Moment habe ich aber grade ein anderes Problem, ich will jetzt auch runde Räume einfügen.
Dabei zeichne ich mit Hilfe des Satz des Pythagoras, zwei Kreise der erste ist am ende die Mauer der zweite Boden.

hier der Code...

Code:
		int x = 0;
		int y = 0;
		int z = 13;
		
		//-------------------------------- kreis 1
		for(int count_a = 0; count_a < 100; count_a++){
			
			
			for(int count_b = 0; count_b < 100; count_b++){
							
				if(((int) Math.sqrt(((int)x-56)*((int)x-56)+((int)y-56)*((int)y-56)))<(int)z){
					
					dungeon[y][x][0]=1;	
					
					x++;

				}
			
				
		}
			x =0;
			y++;
		
		}
		
		x=0;
		y=0;
		z=12;

		//-------------------------------- kreis 2
		for(int count_a = 0; count_a < 100; count_a++){
			
			
			for(int count_b = 0; count_b < 100; count_b++){
								
				if(((int) Math.sqrt(((int)x-56)*((int)x-56)+((int)y-56)*((int)y-56)))<(int)z){
					
					dungeon[y][x][0]=3;
					
					x++;
				}
			
				
		}
			x =0;
			y++;
		}
		
		
	
		
		output.main(null);

		
		}
		

	

	
	
	
	
}


Dabei sieht das Ergebnis so aus.


Was ich brauche ist aber das Hier.



Ich habe eine Idee wie ich es im Nachhinein ändern kann aber mir wäre es lieber wen er es gleich beim ersten mal richtig macht und wollte fragen ob ihr da weiter wisst.

[edit:] Hier mal drei Bilder davon was der Generator aktuell mit verschiedenen Parametern erzeugt :)

 
Zuletzt bearbeitet:
Ich habe nicht so viel Ahnung aber meine Karte ist ein Array [y][x][layer] und ich zeichne die wand in dem ich zb dungeon[50][50][0] auf 1 setze.

Wen ich das mit draw oval mache müsste ich ja irgendwie die Koordinaten jedes Pixels des Kreise/Ovales auf meine Map übertragen und ich weis nicht wie das geht.

Mein Ansatz mit jetztigen Methode am ende die ecken zu füllen wäre.

Code:
if(Main.dungeon[position_y-1][position_x][0] == 1 && Main.dungeon[position_y][position_x+1][0] == 1&& Main.dungeon[position_y-1][position_x+1][0]==3){
			Main.dungeon[position_y][position_x][0] = 1;}

Dabei schaut er in dem Beispiel ob er sich auf einem freien Feld befindet, wen dann rechts und unterhalb des Feldes eine Mauer ist und diagonal nach unten rechts Boden, füllt er das leere Feld mit einer Mauer.

Falls jemand eine Bessere Idee hat nur her damit.
 
Zurück
Oben