Swing Aktualisieren eines JPanels

airglide

Mitglied
Hallo zusammen 😉

Ich möchte Daten, die in einer ArrayList abgespeichert sind zeichnen. Das klappt schon ganz gut, jedoch möchte ich jedesmal, wenn ich neue Daten hinzufüge, die Zeichnung aktualisieren und nicht erst am Schluss die gesamten Daten erhalten.

Ich hab schon ziemlich lange herumgesucht, und bin auf die Methoden repaint() und validate() gestossen. Habe schon verschiedene Kombinationen versucht, ebenfalls mit einem separaten Thread der repaint aufrufen sollte...

bin wirklich ahnungslos hoffe ihr könnt mir helfen

Java:
class plotPanel extends JPanel{
			public void paintComponent(Graphics g){
				super.paintComponents(g);
				
				final double dif = 20.0;
				Graphics2D g2d = (Graphics2D) g;
				
				int length = getWidth();
				int width = getHeight();		
				
				xAxis = new Line2D.Double(dif,(width/2),length-dif,width/2);
				yAxis = new Line2D.Double(length/2,dif,length/2,width-dif);
				
				g2d.draw(xAxis);
				g2d.draw(yAxis);
				
				g2d.setColor(Color.ORANGE);	
				for(int i=0;i < dataList.size();i++)
				{
				g2d.fill(new Ellipse2D.Double((length/2)+dataList.get(i).getX()-1.5,(width/2)+dataList.get(i).getY()-1.5, 3.0, 3.0));
				}
				
			}

das ganze liegt natürlich auf einem Frame, das ein JPanel enthält

[Java]
void gui(){
frame = new JFrame();
plot = new plotPanel();
plot.setPreferredSize(new Dimension(250,300));

mainPanel = new JPanel();
mainPanel.add(plot);

frame.add(BorderLayout.CENTER,mainPanel);
}
[/Java]

Das ganze wird gezeichnet, jedoch leider erst am Schluss, wenn ich das Fenster minimiere, was repaint afrufen sollte, wird das ganze frame schwarz und erst am ende des Programmes wird es neu gezeichnet

Danke für eure hilfe

airglide
 
> jedoch möchte ich jedesmal, wenn ich neue Daten hinzufüge, die Zeichnung aktualisieren und nicht erst am Schluss die gesamten Daten erhalten

das läßt vermuten dass irgendwo eine längerfristige Aktion läuft, die Daten hinzufügt, davon hast du keinen Code gepostet..,
falls diese Aktion aus einem Button-Listener oder so, jedenfalls von der GUI gestartet wird,
muss sie in einen separaten Thread verschoben werden,

solange der GUI-Thread, der die Listener ausführt, damit beschäftigt ist, kann er nicht zeichen
 
genau dass ist der fall, ich habe ein ActionListener der darauf wartet, dass man einen Button klickt, darin werden die daten eigelesen.

Wo und wie muss ich jetzt diesen Thread hinschreiben?

dachte an sowas:

[Java]
class Repaint implements Runnable{
public void run(){
plot.repaint();
}
}
[/Java]

[Java]
Repaint rpnt = new Repaint();
Thread meinThread = new Thread(rpnt);
meinThread.start()
[/Java]

Ich muss also den Thread vom actionListener starten?

danke für die schnelle hilfe 😉
 
Zuletzt bearbeitet:
Warum ein ActionListener, der darauf wartet dass ein Button geklickt wird? :autsch: Wäre es nicht viel geschickter den ActionListener gleich an den Button anzuheften?
 
also ich habe einfach verschiedene buttons die mit .addActionListener(new Listener()) implementiert werden, stand so in meinem java buch 🙂

in wie fern ist der code richtig? es funktioniert immer noch nicht so wie ich will..
 
Zeig mal das Codefragment, wo du ursprünglich repainten wolltest. Nur repaint in einen Thread auszulagern wird nichts bringen, da der Repaint-Vorgang sowieso von einen anderen Thread ausgeführt wird.
 
Java:
public void actionPerformed(ActionEvent event)
			{					
				
				try {
					// Verbindungsaufbau zu Gerät						
					}
					
					for (int j = 0; j < numberOfMeasurements; j++)
					{
					Daten einlesen

					
					// save in ArrayList
					plot.reprint();

					/*Repaint rpnt = new Repaint();
					Thread meinThread = new Thread(rpnt);
					meinThread.start();*/
					}
				
				
				
			}
		}
[/Java]

natürlich noch catch clauseln und so, der sinn wäre einfach dass er die Klasse plotPanel neu erstellt und dann einzeichnet
 
Zuletzt bearbeitet:
Versuche es so in etwa:

Java:
public void actionPerformed(ActionEvent event) {
	new Thread("\"Get Data from Device, handle its and repaint\"-Thread") {
		public void run() {
			String[] someData = null;
			
			try {
				connectToDevice();
				someData = getDataFromDevice();
			} catch(IOException e) {
				e.printStackTrace();
			} finally {
				disconnectFromDevice();
			}
			
			for (int j = 0; j < someData.length; j++) {
				workWithData(j, someData);
				plot.repaint();					
				Thread.yield(); //Give other Threads more time.
			}
		}
	}.start();
}
private void workWithData(int j, String[] someData) {
	//TODO Do what you ever want with the data.
}
private String[] getDataFromDevice() {
	//TODO Get data here.
	return(null);
}
private void connectToDevice() throws IOException {
	//TODO Connect here.
}
private void disconnectFromDevice() {
	//TODO Disconnect here.
}
 
wow super es hat funktioniert!! dankee 😉

also wie sieht jetzt die theorie dazu aus? immer wenn ich ein actionlistener habe brauche ich einen neuen thread wenn ich etwas akutalisiern möchte?

ich hatte noch ein zweites Problem, es zeichnet es aber irgendwie ist das ganze beim zweiten mal verschoben und ich sehe einen knopf als bild in diesem frame der nicht da sein sollte 😛

habe einfach frame.repaint gewählt, dass es das ganze neu zeichnet dann funktioniert es

vielen vielen dank, hast mir echt weitergeholfen 😉
 

Zurück
Oben