# Mehrere JComponents übereinander



## nicolas (3. Nov 2005)

hallo zusammen,

ich habe eine jcomponent programmiert, die häufig neu gezeichnet wird. nun müsste aber eigentlich nur ein teil dieser komponente neu gezeichnet werden.
kann man in swing irgendwie komponenten übereinanderlagern?

ich habs mal folgendermassen probiert. ich benutze als layoutmanager die tablelayout library. da kann man eine art tabelle angeben und die components in die zellen platzieren. nun habe ich zwei jcomponents in dieselbe zelle gesetzt, was auch funktioniert.
die jcomponents werden über einen listener informiert, wenn sich etwas geändert hat und werden dann neu gezeichnet. wenn ich jedoch eine komponente von diesen zwei übereinanderliegenden neu gezeichnet wird, wird die paintComponent() der darunterliegenden komponente auch aufgerufen. wie kann ich das verhindern? kann man komponenten in swing überhaupt unabhängig voneinander überlagern?

thanx und gruss,
nicolas


----------



## André Uhres (4. Nov 2005)

"paintComponent" wird normalerweise sooft aufgerufen wie nötig.
Wenn z.B. Die Anwendung von einer anderen überdeckt wird und dann
wieder aufgedeckt wird, dann werden alle "paintComponent" Methoden
aufgerufen die nötig sind um den Inhalt der Anwendung neu zu zeichnen.

Seit 1.5 kann allerdings mit "setComponentZOrder" die Reihenfolge festgelegt
werden in der die Komponenten gezeichnet werden. Wo Komponenten sich
überlagern, wird die Komponente mit dem niedrigeren "z-order" über die
Komponente mit dem höheren "z-order" gezeichnet.

Vielleicht gibt es einen anderen Weg, das zu erreichen was du willst.
Aber für mich ist nicht klar was du eigentlich bezwecken willst.

```
/*
 * Ueberlagern_.java
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Ueberlagern_ extends JFrame {
    public Ueberlagern_() {
        super("Ueberlagern");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        //JComponents erzeugen:
        toolbar = new JToolBar();
        button1 = new JButton("A");
        button2 = new JButton("B");
        mainPanel = new JPanel();
        panel_A = new Panel_1(0,0);
        panel_B = new Panel_1(20,20);
        //Layout:
        toolbar.add(button1);
        toolbar.add(button2);
        toolbar.setOrientation(JToolBar.VERTICAL);
        getContentPane().add(toolbar, BorderLayout.WEST);
        panel_A.setBackground(Color.green); 
        panel_B.setBackground(Color.yellow); 
        mainPanel.setLayout(null);
        mainPanel.add(panel_A);
        mainPanel.add(panel_B);
        mainPanel.setComponentZOrder(panel_A,0);
        mainPanel.setComponentZOrder(panel_B,1);
        getContentPane().add(mainPanel, BorderLayout.CENTER);
        //Listeners:
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                rot = !rot;
                if(rot) panel_A.setBackground(Color.red);
                else panel_A.setBackground(Color.green);
                mainPanel.repaint();
            }
        });
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                blau = !blau;
                if(blau) panel_B.setBackground(Color.blue);
                else panel_B.setBackground(Color.yellow);
                mainPanel.repaint();
            }
        });
    }
    
    public static void main(final String args[]) { new Ueberlagern_().setVisible(true); }
    private Panel_1 panel_A, panel_B;
    private JButton button1, button2;
    private JPanel mainPanel;
    private JToolBar toolbar;
    private boolean rot, blau;
}
class Panel_1 extends JPanel{
    public Panel_1(int x, int y){
        setLocation(x,y);
        setSize(getPreferredSize());
    }
    public Dimension getPreferredSize(){
        return new Dimension(111,111);
    }
    public void paintComponent(final Graphics g){
        super.paintComponent(g);
        g.drawRect(0,0,100,100);
        g.drawRect(10,10,100,100);
    }
}
```


----------



## nicolas (4. Nov 2005)

ich schreibe mein programm für java 1.4, daher fällt die 1.5 variante schon mal weg.

mein jcomponent ist eben ziemlich aufwändig und wird alle 50ms neu gezeichnet. jedoch müsste eben nur ein arc2d neu gezeichnet werden, der rest verändert sich nicht.
nun ist es eben ziemlich rechenaufwändig, alle 50ms die ganzen berechnungen zu machen und die ganze komponente neu zu zeichnen. diese berechnungen wollte ich dadurch verhindern.
sonst jemand eine idee, wie ich das lösen könnte?


----------



## André Uhres (4. Nov 2005)

Nur damit ich dich richtig verstehe:
der untere JComponent ist der rechenaufwendige und
der obere JComponent derjenige der öfters neu zu zeichnen ist 
( mit "setOpaque(false)", also durchsichtigem Hintergrund ).
Ist das so richtig? :### 

Wenn ja, dann könnte man vielleicht von dem rechenaufwendige JComponent
ein BufferedImage machen, das schneller gezeichnet werden kann als wenn
man die zeitaufwendigen Berechnungen jedesmal neu durchlaufen muss.  
Der untere JComponent braucht dann nur noch das fertige BufferedImage zu zeichnen.  :toll: 

```
/*
 * Ueberlagern_2.java
 */
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
public class Ueberlagern_2 extends JFrame {
    public Ueberlagern_2() {
        super("Ueberlagern 2");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(400,300);
        setLocationRelativeTo(null);
        //JComponents erzeugen:
        toolbar = new JToolBar();
        button1 = new JButton("A");
        button2 = new JButton("B");
        mainPanel = new JPanel();
        panelAufwendig = new PanelAufwendig(0,0);
        panelAufwendig.setColor(Color.green);
        image = createImage(panelAufwendig);
        panel_A = new Panel_A(0,0);
        panel_A.setImage(image);
        panel_B = new Panel_B(20,20);
        panel_B.setColor(Color.yellow);
        //Layout:
        toolbar.add(button1);
        toolbar.add(button2);
        toolbar.setOrientation(JToolBar.VERTICAL);
        getContentPane().add(toolbar, BorderLayout.WEST);
        mainPanel.setLayout(null);
        mainPanel.add(panel_B);
        mainPanel.add(panel_A);
        getContentPane().add(mainPanel, BorderLayout.CENTER);
        //Listeners:
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                rot = !rot;
                setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                if(rot) panelAufwendig.setColor(Color.red);
                else panelAufwendig.setColor(Color.green);
                image = createImage(panelAufwendig);
                panel_A.setImage(image);
                mainPanel.repaint();
                setCursor(Cursor.getDefaultCursor());
            }
        });
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent evt) {
                blau = !blau;
                if(blau) panel_B.setColor(Color.blue);
                else panel_B.setColor(Color.yellow);
                mainPanel.repaint();
            }
        });
    }
    public static BufferedImage createImage(final JComponent component){
        component.setOpaque( true );
        Dimension d = component.getSize();
        BufferedImage image = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setClip(new Rectangle(0, 0, d.width, d.height) );
        component.paint( g2d );
        g2d.dispose();
        return image;
    }
    
    public static void main(final String args[]) { new Ueberlagern_2().setVisible(true); }
    private PanelAufwendig panelAufwendig;
    private Panel_A panel_A;
    private Panel_B panel_B;
    private JButton button1, button2;
    private JPanel mainPanel;
    private JToolBar toolbar;
    private boolean rot, blau;
    private BufferedImage image;
}
class PanelAufwendig extends JPanel{
    public PanelAufwendig(int x, int y){
        setOpaque(true);
        setLocation(x,y);
        setSize(getPreferredSize());
    }
    public Dimension getPreferredSize(){
        return new Dimension(111,111);
    }
    public void paintComponent(final Graphics g){
        super.paintComponent(g);
        g.setColor(color);
        g.drawRect(0,0,100,100);
        g.drawRect(10,10,100,100);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
    public void setColor(final Color color){
        this.color = color;
    }
    private Color color;
}
class Panel_A extends JPanel{
    public Panel_A(int x, int y){
        setOpaque(true);
        setLocation(x,y);
        setSize(getPreferredSize());
    }
    public Dimension getPreferredSize(){
        return new Dimension(111,111);
    }
    public void paintComponent(final Graphics g){
        super.paintComponent(g);
        g.drawImage(image,0,0,null);
    }
    public void setImage(final BufferedImage image){
        this.image = image;
    }
    private BufferedImage image;
}
class Panel_B extends JPanel{
    public Panel_B(int x, int y){
        setOpaque(false);
        setLocation(x,y);
        setSize(getPreferredSize());
    }
    public Dimension getPreferredSize(){
        return new Dimension(111,111);
    }
    public void paintComponent(final Graphics g){
        super.paintComponent(g);
        g.setColor(color);
        g.drawRect(0,0,100,100);
        g.drawRect(10,10,100,100);
    }
    public void setColor(final Color color){
        this.color = color;
    }
    private Color color;
}
```


----------

