repaint()-Problem - 50% CPU-Auslastung

hodoe

Mitglied
Hallo,

ich habe mal den Code angehängt. Ich möchte gerne in mehreren Reitern Text auch Grafik darstellen.
Dazu habe ich ein JPanel angelegt, in dem ich zeichne. Problem: Durch das repaint() habe ich eine CPU-Auslastung von 50%. Lasse ich das weg, dann wird das Pane nicht so dargestellt, wie ich es gerne hätte. Wie mache ich es richtig?

Gruß
Holger

Java:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LayoutManager;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;



public class Test extends javax.swing.JFrame  
{
	private static final long serialVersionUID = 1L;
	private 	ArrayList<JSensorPanel> sensorBlatt = new ArrayList<JSensorPanel>();//dies sind die einzelnen Reiter
	private 	JTabbedPane 			jTabbedPane1; 			//das ist der Container für die Reiter

	public Test() 
	{
		super("Test");
		initGUI();    	     
	}
		
	
	
	
	
	@SuppressWarnings("deprecation")
	private void initGUI() 
	{
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		getContentPane().setLayout(null);

    	jTabbedPane1 = new JTabbedPane();
		jTabbedPane1.setBounds(7, 85, 1085, 671);
		sensorBlatt.add(new JSensorPanel());	
		jTabbedPane1.addTab("Test", null, sensorBlatt.get(0), null);
	
		this.setSize(1109, 871);
		this.setResizable(false);
		this.setPreferredSize(new java.awt.Dimension(1109, 871));
		pack();
		
	}
	
	//****************************************************************************************
	//*** JSensorPanel ist eine Erweiterung der Klasse JPanel für die grafische Oberfläche ***
	//****************************************************************************************
	public class JSensorPanel extends JPanel
	{
	    
	    //Alle Konstruktoren von JPanel Übernehmen....
	    public JSensorPanel() 
	    {
	        this(true);
	    }

	    public JSensorPanel(LayoutManager layout) 
	    {
	        this(layout, true);
	    }

	    public JSensorPanel(boolean isDoubleBuffered) 
	    {
	        this(new FlowLayout(), isDoubleBuffered);
	    }

	    public JSensorPanel(LayoutManager layout, boolean isDoubleBuffered) 
	    {
	        super(layout, isDoubleBuffered);

			this.setLayout(null);
			this.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
		
				
			getContentPane().add(jTabbedPane1);
		}
	    
	    	    
	    public void paintComponent(Graphics g)
	    {
	    	super.paintComponent(g); 
	    	Graphics2D g2 = (Graphics2D) g;
	    	super.paintComponent(g2); 
	       	g2.setColor(Color.white);
	    	g2.fillRect(0,0,1077,639);
	    	g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
	    	g2.setColor(Color.lightGray);
	    	g2.draw(new Rectangle2D.Double(3, 264, 1072, 342));
		
    		//Hinweistext
    		g2.draw(new Rectangle2D.Double(3, 610, 1072, 27));

	    	AffineTransform af = new AffineTransform();
	    	af.rotate(Math.toRadians(270),30,530); //um 90 Grad drehen
	    	g2.setTransform(af); //Drehung auf das Kosy übertragen

	    	af.rotate(- Math.toRadians(270),30,530); //Kosy zurück drehe, da sonst alles um 90 Grad gedreht gezeichent wird
	    	g2.setTransform(af);
	     			
	    	g2.draw(new Line2D.Double(80, 275, 80, 595));
	    	g2.draw(new Line2D.Double(80, 275, 75, 285));
	    	g2.draw(new Line2D.Double(80, 275, 85, 285));
	    	g2.draw(new Line2D.Double(80, 595, 75, 585));
	    	g2.draw(new Line2D.Double(80, 595, 85, 585));

	    	g2.draw(new Line2D.Double(80, 435, 1050, 435));
	    	g2.draw(new Line2D.Double(1050, 435, 1040, 430));
	    	g2.draw(new Line2D.Double(1050, 435, 1040, 440));
	    	    	
	    	repaint();
	    	
	    }
	}
	

	 
	public static void main(String[] args) 
		{
			//Ab hier wird der Splashscreen aufgebaut. Wartezeit ca. 50 * 100ms
	    
					
			SwingUtilities.invokeLater(new Runnable() 
			{
				public void run() 
				{
					Test inst = new Test();
					inst.setLocationRelativeTo(null);
					inst.setVisible(true);
				}
			});
		}
}
 
Das Problem an deiner jetzigen Methode ist, dass ein repaint-Kommando unmittelbar auf ein anderes folgt. Die CPU wird also dazu verdonnert ohne Pause zu arbeiten. Dies musst du umgehen, indem du den repaint-Aufruf in einen zweiten Thread auslagerst, der außerdem noch ein sleep-Aufruf beinhaltet, um der CPU zwischen dem Neuzeichnen die Möglichkeit zu geben noch was anderes zu machen.

Du hast nicht genauer geschrieben warum du ein repaint benötigst. Wenn du keine Inhalte hast die sich ständig ändern, dann sollte es reichen repaint z.B. mit Hilfe eines Listeners aufzurufen. Dann erfolgt der repaint-Aufruf eben nur, wenn z.B. gescrollt wird, grafisch dargestellte Inhalte geändert werden usw. Das ständige Neuzeichnen durch einen zweiten Thread wäre dann Ressourcenverschwendung.
 
Hallo, danke für die Antwort. Ein Aufruf mit
Java:
	    	try
			{
				Thread.sleep(50); //50
			}
			catch(InterruptedException e)
			{		
				catchAusgabeInterruptedException(e);
			}
			
	    	repaint();

bringt Entspannung. Das Auslagern in einen ChangeListener habe ich probiert. Es ging aber nicht. Mein Programm liest Daten ein und stellt diese im oberen Teil des Fensters dar. Unten erscheint dann noch ein Diagramm. Dann ändert sich nichts mehr. Das Problem ist, wenn kein repaint() aufgrufen wird, dass dann die Grafik nicht im unteren Teil sauber aufgebaut wird.

Gruß
Holger
 
Dann lade als erstes die Daten und stelle dann das vollständige GUI dar. Für solche Fälle gibt es schon fertige Klassen mit denen du das Laden visualisieren kannst, wie z.B. JProgressBar, ProgressMonitor oder ProgressMonitorInputStream.
 

Zurück
Oben