speicherschonendere lösung?

darkeye2

Bekanntes Mitglied
Hallo,

kaum hat sich ein problem gelöst, schon hab ich bei einem anderen programm ein neus Problem^^

Also ich habe ein feld, dass sehr viele punkte beinhalten soll (anzahl variiert zwischen 100 und 10000)
nun kann jeder punkt eigentlich 4 zustände haben:
-unset
-unset_selected
-set_blue
-set_red
jeder dieser zustände wird durch ein bild repräsentiert, welches an der entsprechenden stelle des feldes sein soll.

Mein Problem: momentan stelle ich jeden punkt durch ein JLabel da, solnge ein punkt unset ist hat er einen mouselistener und änderst sein icon, wenn man mit der maus drüber geht und wenn man ihn anklickt wird das label gelöscht und ein neues wird erstellt, dass dann ein set repräsentiert (hat je nach farbe eine anderes icon).
Bei 1000 JLabel ist es schon etwas viel und sehr speicherfressend, deswegen will ich das jetzt anders machen, hat jemand eine Idee, wie man das am besten macht?

MfG
darkeye
 
G

Gast2

Gast
Du kannst das ganze z.b. auf ein BufferedImage malen und dann dieses BufferedImage anzeigen. Dann wird aber natürlich etwas schwieriger mit den MouseListenern, du müsstest dann die Koordinaten der Maus auf dein Feld umrechnen.
 

darkeye2

Bekanntes Mitglied
hmm, wie kann ich ein bufferedImage mit transparenten hintergrund erzeugen? (weil auf meienen jpanel ist bereits ein feld aufgezeichnet, dass man trotzdem noch sehen soll)
.... Ja, das mit dem MousListener kann ich mir bei einem BufferedImage net ganz vorstellen, immer wenn die maus bewegt wird müsste man ja neu berechnen, ob überhaupt ein punkt selectiert ist, wenn ja müsste man diese stelle neu zeichnen und wenn gedrückt wird schon wieder das ganze bild neu zeichnen?
 
G

Gast2

Gast
hmm, wie kann ich ein bufferedImage mit transparenten hintergrund erzeugen?
Da bin ich überfragt. Evtl. kannst du den Frame dazu bringen sich auf deinem BufferedImage zu zeichnen, dadurch würde das bufferedimage durchsichtig erscheinen.
Aber vllt. hat jemand anderes ja noch ne bessere idee :)
 

Wildcard

Top Contributor
Nimm eine JComponent. Der übergibst du ein Modell das deine Punkte repräsentiert. Die JComponent zeichnet den Zustand dieses Modells in paintComponent. Um den Mouse Listener musst du dich tatsächlich selbst kümmern denn 10000 Labels sind einfach 'too much'
 

Marco13

Top Contributor
Hm. Natürlich sollte man Modell und View trennen, aber in diesem Fall könnte man (eventuell! Je nachdem, was damit am ENde erreicht werden soll!) so weit gehen, das BufferedImage als "Modell" anzusehen. Wie man einen int[1024*768] effizient auf den Bildschirm bringen soll, ohne ihn in ein BufferedImage einzuwickeln, wüßte ich jetzt nicht.

Insgesamt klingt das nach sowas (nur schnell hingeschrieben)
Java:
class ThePanel extends JPanel implements MouseListener
{
    private BufferedImage image = ....

    public ThePanel()
    {
        setOpaque(false);
    }
    public void paintComponent(Graphics g)
    {
        g.drawImage(image,0,0,this); // Bild im Hintergrund
        super.paintComponent(g); // Buttons usw. im Vordergrund...
    }
    public void mouseClicked(MouseEvent e)
    {
        int rgb = image.getRGB(e.getX(), e.getY());
        int newRGB = ...
        image.setRGB(e.getX(), e.getY(), newRGB);
    }
}
 

ARadauer

Top Contributor
grundsätzlich würd ich schon JLabel verwenden wenn das klappt.
ich würde jedoch die das feld als int oder short array halten.

beim zeichnen ein JLabel instanzieren.
ersten wert setzen, zeichnen, zweiten wert setzen, zeichnen .....
Eine JTable macht es auch so, die ganzen Felder der Tabelle sind in Wirklichkeit immer das gleiche das wiederverwendet wird...
 

darkeye2

Bekanntes Mitglied
Schon mal danke für die Ideen,werde mir da mal gedanken machen, um nochmal genau zu verdeutlichen, worum es geht, hier eine etwas ausführlicherere erklärung:
Es geht um ein spielfeld, das ganze spielfeld besteht aus einen hintergrund (kästchen, die größe wird vom aktuellen zoomfactor bestimmt)
Und eben an jedem eckpunkt ein der kästchen soll ein punkt sizten, diese hab ich bereits als bilder vorbereitet. Zu Anfang sind alle punkte weiß also wird wird das bilde white_small.png an jeden eckpunkt gesetzt, bei dürbergehen mit der Maus über einen weißen punkt soll er einen gelben rahmen riegen (also an stelle von white_small.png soll jetzt selected_small.png an der entsprechenden stelle sein) wird nun draufgeklickt soll der punkt durch die farbe des spielers ersetzt werden. also entweder red_small.png oder blue_small.png diese bilder sollen nicht mehr auf klicks oder mouseOver reagieren.

MfG
darkeye
 

darkeye2

Bekanntes Mitglied
Ich mache wohl irgendwas falsch, bei mir ist der speicherverbrauch kein bisschen gesunken, obwohl ich jetzt ein bild zeichne ...
code:
Java:
	OpperatingField(int s){
		size = s+1;
		field = new boolean[size][size];
		redField = new boolean[size][size];
		blueField = new boolean[size][size];
		setImage(size);
		preparePoints(radius);
		spielFeld = new OpticalPane();
		spielFeld.setBounds(0, 0, gridsize*size+size+10, gridsize*size+size+10);
		this.setPreferredSize(new Dimension(gridsize*size+size+10, gridsize*size+size+10));
		this.setLayout(null);
		this.setVisible(true);
		this.add(spielFeld);
	}
	
	
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(background, 0, 0, this);
    }
	
    
    private  void setImage(int size){
    	int iw = gridsize*size;
    	background = new BufferedImage(iw, iw, BufferedImage.TYPE_INT_RGB);
    	gi = background.getGraphics();
    	gi.setColor(Color.white);
    	gi.fillRect(0, 0, iw, iw);
    	gi.setColor(Color.black);
    	for(int i =0; i<size; i++){
    		gi.drawLine(gridsize*i, 0, gridsize*i, iw);
    		//gi.drawLine(gridsize*i+1, 0, gridsize*i+1, iw);
    		gi.drawLine(0, gridsize*i, iw, gridsize*i);
    		//gi.drawLine(0, gridsize*i+1, iw, gridsize*i+1);
    	}
    	
    }

//methode für die punkte:
    private class OpticalPane extends JPanel implements MouseListener{
		private static final long serialVersionUID = -2108627378088929277L;
		private BufferedImage game;
		
		OpticalPane(){
			this.setOpaque(false);
			this.setPreferredSize(new Dimension(gridsize*size+size+10, gridsize*size+size+10));
			createGame();
			repaint();
			
		}
		
	    public void paintComponent(Graphics g)
	    {
	        super.paintComponent(g);
	        g.drawImage(game, 0, 0, this);
	    }
	    
	    private void createGame(){
	    	game = new BufferedImage(gridsize*size, gridsize*size, BufferedImage.TYPE_INT_ARGB_PRE);
	    	Graphics g1 = game.getGraphics();
			for(int i =1; i< size; i++){
				for(int n =1; n< size; n++){
					if(!field[i][n]){
						g1.drawImage(white, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}else if(redField[i][n]){
						g1.drawImage(red, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}else if (blueField[i][n]){
						g1.drawImage(blue, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}
				}
			}
	    	
	    	
	    }
 

darkeye2

Bekanntes Mitglied
keiner ne Idee, woran das liegen kann? wie werden denn bei anderen auch anspuchsvollereren Spielen die Karten dargestellt? es kann doch net sein, dass ich schon bei so nen kleinen Spielfeld 150MB RAM verbrauche.
 

Marco13

Top Contributor
Java:
        field = new boolean[size][size];
        redField = new boolean[size][size];
        blueField = new boolean[size][size];
Spannend wäre jetzt, die du das machen würdest, wenn du 16.7 Millionen Farben darstellen wolltest... ... ... ...

Wie auch immer: Wie "misst du denn den Speicherverbrauch?
 

darkeye2

Bekanntes Mitglied
wegen farben:
da in dem fall nur 2 spieler auf einmal spielen können ist das ne recht angenehme art zu unterscheiden, welche punkte wem gehören ... , würde ich die farbe frei wählbar machen würde ich intern trotzdem redField und blueField verwenden und nach außen hin einfach per JColorChooser die farbe wählen lassen, ist aber hier net der fall.

Speicherverbrauch:
im taskmanager steht da, wie viel ram das prog grad verbraucht ... und je nach feldgröße ändert sich dieser, wobei ich mit jlabels eigentlich einen genau so großen verbrauch hatte ... . Es ist mir ein rätsel, was ich so falsch mache, es gibt in java programmiert Spiele, die riesige welten darstellen, in dennen sich was bewegt und wird weniger ram verbraucht als bei mir beim anzeigen des spielfeldes, das eigentlich gar net so groß ist (zumindest das was ich getestet habe) .

Hoffe es kann jemand helfen.
 

Marco13

Top Contributor
Was der Taskmanager anzeigt ist nur SEHR bedingt (d.h. "nicht" ;) ) aussagekräftig. Er zeigt in erster Näherung an, wie viel Speicher der VM zugesichert ist. Wie viel tatsächlich (und wofür) belegt ist, erkennt man am ehesten mit einem Profiler. Im Zweifelsfall mit der "VisualVM", die beim JDK dabei ist.
 

darkeye2

Bekanntes Mitglied
ok, danke für den tipp, also die grundsätzlich dinge sind soweit in Ordnugn, ich kann ein Spielfeld erzeugen und ich kann punkte setzen, das Problem, was ich jetzt hab der erste gesetzte punkt ist net da^^ er wird zwar als gesetzt markiert, aber ist trotzdem weiß (und nicht wie es beim test sein sollte blau.

der code für den Mauslistener und die zugehörigen methoden, die für das Problem relefant sein könnten:
Java:
 private class OpticalPane extends JPanel implements MouseListener{
		private static final long serialVersionUID = -2108627378088929277L;
		private BufferedImage game;
		
		OpticalPane(){
			this.setOpaque(false);
			this.setPreferredSize(new Dimension(gridsize*size+size+10, gridsize*size+size+10));
			this.addMouseListener(this);
			createGame();
			repaint();
			
		}
		
	    public void paintComponent(Graphics g)
	    {
	        super.paintComponent(g);
	        g.drawImage(game, 0, 0, this);
	    }
	    
	    private void setPoint(Point p, int mode){
	    	Graphics gF = spielFeld.getGraphics();
	    	if(mode == 1)
	    		gF.drawImage(selected, (p.x*gridsize)-radius, (p.y*gridsize)-radius, this);
	    	if(mode == 2)
		    	gF.drawImage(white, (p.x*gridsize)-radius, (p.y*gridsize)-radius, this);
	    	if(mode == 3){
		    	gF.drawImage(getColor(), (p.x*gridsize)-radius, (p.y*gridsize)-radius, this);
		    	field[p.x][p.y] = true;
		    	
	    	}
	    	
	    }
	    
	    private Image getColor(){
	    	if(yourColor == 1){
	    		return blue;
	    	}else{
	    		return red;
	    	}
	    }
	    
	    private void createGame(){
	    	game = new BufferedImage(gridsize*size, gridsize*size, BufferedImage.TYPE_INT_ARGB_PRE);
	    	Graphics g1 = game.getGraphics();
			for(int i =1; i< size; i++){
				for(int n =1; n< size; n++){
					if(!field[i][n]){
						g1.drawImage(white, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}else if(redField[i][n]){
						g1.drawImage(red, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}else if (blueField[i][n]){
						g1.drawImage(blue, (i*gridsize)-radius, (n*gridsize)-radius, this);
					}
				}
			}
	    	
	    	
	    }
	   

		public void mouseClicked(MouseEvent arg0) {
			
		}

		public void mouseEntered(MouseEvent arg0) {
			entered=true;
			new Thread(
					new Runnable(){
						public void run() {
							while(entered){
								tmpPoint = getPossition(spielFeld.getMousePosition());
								if(  lastTmpPoint.x != 0 && lastTmpPoint.y != 0 && lastTmpPoint.x != tmpPoint.x && lastTmpPoint.y != tmpPoint.y && !field[lastTmpPoint.x][lastTmpPoint.y] ){
									setPoint(lastTmpPoint, 2);
								}
								if(  tmpPoint.x != 0 && tmpPoint.y != 0 && !field[tmpPoint.x][tmpPoint.y] ){
									setPoint(tmpPoint, 1);
								}
								lastTmpPoint = tmpPoint;
								tmpPoint = null;
								try {
									Thread.sleep(80);
								} catch (InterruptedException e) {
									e.printStackTrace();
								}
							}
							
						}
						
					}
			).start();
		}

		public void mouseExited(MouseEvent arg0) {
			entered = false;
			
		}

		public void mousePressed(MouseEvent arg0) {
			
		}

		public void mouseReleased(MouseEvent arg0) {
			tmpPoint = getPossition(spielFeld.getMousePosition());
			if(  tmpPoint.x != 0 && tmpPoint.y != 0 && !field[tmpPoint.x][tmpPoint.y] ){
				setPoint(tmpPoint, 3);
			}
			
		}
    	
    }
	
    private Point getPossition(Point p){
    	Point opticalP = new Point();
    	float opticalX = (float)(p.x+radius)/(float)gridsize;
    	float opticalY = (float)(p.y+radius)/(float)gridsize;
    	if( opticalX <= Float.valueOf(new String((int) opticalX+".3"))  &&  opticalY <= Float.valueOf(new String((int) opticalY+".3"))){
    		opticalP.setLocation((int)opticalX, (int)opticalY);
    	}
    	
    	return opticalP;
    }
 

darkeye2

Bekanntes Mitglied
sorry, dass der code etwas caothisch ist, werde sobald das hier funktioniert mal schauen, dass ich da aufräume und den sauberer hinschreibe.

zu deiner frage, hier paar var deklarationen:
Java:
    private boolean entered = false;
	private Graphics gi;
	private BufferedImage background;
	private Point tmpPoint, lastTmpPoint = new  Point(0,0);
	private OpticalPane spielFeld;
	private int gridsize = 61;
    private int radius = 9;
	private boolean[][] field;
	private boolean[][]  redField;
	private boolean[][]  blueField;
	private String player1=null, player2 = null;
	private int yourColor  = 1;
	private int size;
 

Michael...

Top Contributor
Statt der drei Arrays field, redField, blueField würde ich den Zustand des Spielfelds in einem (z.B. int) Array speichern, das erspart Dir z.B. beim Zeichnen die if-Abfragen.
So wie ich das sehe, zeichnest Du immer alles auf ein BufferedImage, um dieses dann auf die Komponente zu malen. Warum malst Du nicht direkt auf die Komponente? Das Spielfeld selbst kann man ja als Image vorhalten, aber zumindest die Punkte (da diese ja Ihren Zustand verändern können) würde ich direkt in der paintComponent() zeichnen.
 

Marco13

Top Contributor
Dazu gibt's hier im Forum jede Menge Threads. Alles, was auf den Bildschirm gezeichnet wird, muss von der paintComponent-Methode aus gezeichnet werden. Um zu sagen, wie man das im konkreten Fall machen könnte, wurden bisher zu chaotische und zu wenig zusammenhängende Codestücke gepostet.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C Rechnen mit Brüchen, ist meine Lösung soweit richtig? Java Basics - Anfänger-Themen 4
N Ich kriege ganze zeit die Fehlermeldung "Inhalt der Zwischenablage kann nicht in die ausgewählten Elemente eingefügt werden" hat jemand eine Lösung? Java Basics - Anfänger-Themen 6
W Texteingabe - Bedeutung Fehlermeldung, Lösung? Java Basics - Anfänger-Themen 18
M Kennt jemand die richtige Lösung? Java Basics - Anfänger-Themen 7
H Codewars akzeptiert Lösung nicht Java Basics - Anfänger-Themen 29
A Selbe Aufgaben stellung, andere Lösung Java Basics - Anfänger-Themen 7
M Lösung Aufgabe - Java Programmiren lernen für Dummies Java Basics - Anfänger-Themen 11
ZH1896ZH Java-SemesterTest ohne Lösung :( Java Basics - Anfänger-Themen 47
D Beim Programmieren auf die Logisch einfache Lösung kommen. Java Basics - Anfänger-Themen 17
M Hamstersimulator- lösung hilfe benotigt Java Basics - Anfänger-Themen 3
M Hamstersimulator- Lösung? Java Basics - Anfänger-Themen 3
E Mathematische Aufgabe: Antwort entspricht nicht der Lösung Java Basics - Anfänger-Themen 5
W Tipps/Anmerkungen zu meiner Lösung?! Java Basics - Anfänger-Themen 2
H lösung aufgabe Java Basics - Anfänger-Themen 12
J Gleiche Methode in 2 verschiedenen Klassen - Lösung ? Java Basics - Anfänger-Themen 8
P java.lang.ClassCastException Bedeutung und Lösung Java Basics - Anfänger-Themen 3
M Methoden Fehler und finde die Lösung nicht wirklich Java Basics - Anfänger-Themen 6
J RPN Taschenrechner - keine Lösung!! Java Basics - Anfänger-Themen 84
I java.lang.ArrayIndexOutOfBoundsException at lösung.main Java Basics - Anfänger-Themen 3
J Best Practice DOS Fenster mit Befehlszeile (Lösung) Java Basics - Anfänger-Themen 2
S mehrfache if-Abfragen - beste Lösung Java Basics - Anfänger-Themen 1
J Einfache pub/sub Lösung mit ausführlicher Doku Java Basics - Anfänger-Themen 5
D Best Practice Testdaten. Was ist eine saubere Lösung? Java Basics - Anfänger-Themen 3
D Datentypen Datentyperstellung | Kompiler sagt Syntax Error doch ich find keine Lösung Java Basics - Anfänger-Themen 2
V Verstehe die Lösung einer Aufgabe von Grunkurs-Java nicht. Java Basics - Anfänger-Themen 11
P Verstehe Lösung einer Aufgabe von "Grundkurs-Java" nicht Java Basics - Anfänger-Themen 5
E Brauche eine Antwort zum Thema RegEx ( Alternative zur Lösung auch gesucht ) Java Basics - Anfänger-Themen 5
C Lösung für RegEx in Java gesucht Java Basics - Anfänger-Themen 2
S Eine rekursive Lösung Java Basics - Anfänger-Themen 4
G OOP [Eilig] Biete 10€ für Lösung von 2 Grundlagen-Aufgaben Java Basics - Anfänger-Themen 6
C For-Schleife wie kommt man auf die Lösung? Java Basics - Anfänger-Themen 2
M Erste Schritte boolean: ist Zahl Hexadezimal - Lösung verwirrend Java Basics - Anfänger-Themen 6
C Best Practice Was ist die elegantere Lösung bzgl. Klassenaufteilung in Robocode ? Java Basics - Anfänger-Themen 3
O Funktioniert dies? Und gibt es eine bessere Lösung? Java Basics - Anfänger-Themen 6
G Vererbung Lösung Standardproblem Java Basics - Anfänger-Themen 2
J Lösung eines Zahlenintervall wierd an der Falschen Stelle angezeigt. Java Basics - Anfänger-Themen 8
S Bessere Lösung? Java Basics - Anfänger-Themen 4
C Sortierverfahren - allgemeine Lösung? Java Basics - Anfänger-Themen 9
3 Bitte um Hilfe bei Lösung einer Aufgabe Java Basics - Anfänger-Themen 16
M Interval Teilmenge bestimmen - Fehler in meiner Lösung Java Basics - Anfänger-Themen 6
M Suche Korrektor für meine Lösung (FH: Java1 - Übungsklausur) Java Basics - Anfänger-Themen 4
F OOP Wieder mal Zugriffsprobleme... (Lösung am Ende) Java Basics - Anfänger-Themen 11
U JTable viele möglichkeiten, keine Lösung Java Basics - Anfänger-Themen 5
T Objektübergabe - saubere Lösung? Java Basics - Anfänger-Themen 3
S Bessere Lösung zu häufigem instanceof Java Basics - Anfänger-Themen 25
U Rekursive lösung von pascal dreieck Java Basics - Anfänger-Themen 11
S LineNumberReader - bessere Lösung möglich? - Log4J Java Basics - Anfänger-Themen 9
A brauche eine Lösung für Problem bei Moorhuhn-Version Java Basics - Anfänger-Themen 5
C Lösung einer Aufgabe mittels Iteration und Rekursion Java Basics - Anfänger-Themen 12
F Eingabe darf nur 1 oder 0 sein. Meine Lösung macht Probleme. Java Basics - Anfänger-Themen 8
C Frage zu try - catch (saubere Lösung?) Java Basics - Anfänger-Themen 3
G Bessere Lösung für SQL STMNT ? (Schneller?) Java Basics - Anfänger-Themen 4
D Benutzung von globalen Variablen einzigste Lösung? Java Basics - Anfänger-Themen 6
F Servlets, Formulare und ich weiß keine Lösung Java Basics - Anfänger-Themen 4
A Struktur -> Beste Lösung? Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben