# paint/repaint problem mit awt/swing?



## Solour (21. Jul 2005)

hi,

bei mir ergibt sich ein kleiner aber feiner bug...
bin SEHR ungeübt was das GUI bauen unter java angeht also bitte nicht gleich lachen 
erst wenn ihr mir die lösung genannt habt 

hier zwei screenshots mit meinem problem: 










es läuft darauf hinaus, das die methode paint() der classe ConstructPanel seehr oft aufgerufen wird, währen der Bug sichtbar ist. wenn man das menü wieder in ruhe lässt sieht alles wieder normal aus.

und hier noch ein paar auszüge aus dem "wenigen" code den das programm bisher hat:
Die Main.java, hier wird das programm gestartet:

```
package main;

import javax.swing.UIManager;
import gui.main.MainFrame;

public class Main {

	public static void main(String[] args) {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			System.err.println("Exception: " + e.getMessage());
			e.printStackTrace();
		}
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainFrame().setVisible(true);
			}
		});
	}
}
```

hier das hauptfenster der anwendung, welches erstmal hardgecoded ein construct panel erzeugt und im unterenbereich anzeigt (siehe den menu-action-listener ganz unten)

```
package gui.main;

import gui.construct.ConstructPanel;

import java.awt.*;
import javax.swing.*;

import main.Constants;

public class MainFrame extends JFrame {

	private JMenu item_file;
	private JMenuItem item_includeGUI;
	private JPanel lowerArea;
	private JMenuBar mainMenu;

	public MainFrame() {
		initComponents();
	}

	private void initComponents() {
		lowerArea = new JPanel();
		mainMenu = new JMenuBar();
		item_file = new JMenu();
		item_includeGUI = new JMenuItem();

		getContentPane().setLayout(new java.awt.GridLayout(1, 0));
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setTitle(Constants.appName);
		lowerArea.setLayout(new GridLayout(1, 0));
		getContentPane().add(lowerArea);

		item_file.setText(Constants.getWord("file"));

		item_includeGUI.setText(Constants.getWord("include mode"));
		item_includeGUI.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				item_includeGUIActionPerformed(evt);
			}
		});
		item_file.add(item_includeGUI);
		mainMenu.add(item_file);

		setJMenuBar(mainMenu);

		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((screenSize.width - Constants.windowWidth) / 2,
				(screenSize.height - Constants.windowHeight) / 2,
				Constants.windowWidth, Constants.windowHeight);
	}

	private void item_includeGUIActionPerformed(java.awt.event.ActionEvent evt) {
		//TODO: handle incude
		JPanel subPanel = new ConstructPanel(this);
		lowerArea.add(subPanel);
		lowerArea.validate();
	}
}
```

hier dann diese ConstructPanel welches im unteren Bereich des hauptfensters angezeigt wird, also direkt unter der menubar:
dieses erzeugt wie man sieht noch ein GraphPanel welches auf der rechten seite vom splitPane angezeigt werden soll:

```
package gui.construct;

import java.awt.*;
import javax.swing.*;

import main.Constants;

public class ConstructPanel extends JPanel {

	private JFrame mainFrame = null;
	private JSplitPane splitPane = new JSplitPane();
	private JPanel machineGraphic = new GraphPanel();
	private JList machineList = new JList();

	public ConstructPanel(JFrame f) {
		mainFrame = f;
		setLayout(new BorderLayout());
		splitPane.setDividerLocation(Constants.windowWidth / 5);
		machineList.setModel(new AbstractListModel() {
			String[] strings = {"a", "b", "bv", "bvf"};
			public int getSize() {
				return strings.length;
			}
			public Object getElementAt(int i) {
				return strings[i];
			}
		});
		splitPane.setLeftComponent(machineList);
		splitPane.setRightComponent(machineGraphic);
		add(splitPane, BorderLayout.CENTER);
	}

	public void paint(Graphics g) {
		System.out.println("consPain");
		splitPane.repaint();
	}
}
```

dieses GraphPanel soll erstmal blos etwas malen:


```
package gui.construct;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JPanel;

public class GraphPanel extends JPanel {

	public void paint(Graphics g) {
		System.out.println("paint");
		g.drawOval(50, 50, 20, 30);
		g.setColor(Color.black);
		g.drawLine(50, 50, 20, 30);
	}

}
```

hat sicher (naja vielleicht auch nicht sicher) etwas damit zu tun, an welchen stellen wer paint/repaint/update/super.repaint o.ä. aufruft oder eben nicht aufruft, oder diese methoden nicht korrekt überschreibt oder auch für falsche areale aufruft?

wenn sich damit jemand auskennt  bitte melden!

bye

ps: http://java.sun.com/products/jfc/tsc/articles/painting/index.html hier hab ich nachgelesen und hatte mich schon gefreut das es wenigstens alles anzeigte und so, aber diesen bug konnte ich jetzt nicht direkt dadurch lösen..:/


----------



## Beni (21. Jul 2005)

Ich würde den Fehler mal hier suchen:

```
public void paint(Graphics g) {
      System.out.println("consPain");
      splitPane.repaint();
   }
```

Wieso repaint? Wieso überhaupt das ganze Überschreiben?

Du verhinderst hier, dass dieses Panel (und seine Kinder) neu gezeichnet werden.
Das repaint wird dann vielleicht irgendwann mal in Zukunft aufgerufen, sollte es nicht wegoptimiert werden (es würde ja eigentlich reichen, die paint des Panels aufzurufen, damit auch splitPane gezeichnet wird. So sähe es die Standardimplementation jedenfalls vor).

Wenn du weiterhin dieses paint benutzen möchtest, ruf anschliessned "paintComponents" auf.


----------



## Solour (21. Jul 2005)

yop scheint genau das gewesen zu sein!!

 :applaus:  :applaus:  :toll: 

kP warum das da drin war...

*THX!*


----------

