Verständnisfragen im Umgang mit update() und JFrames

achim721

Mitglied
Hallo zusammen. Ich habe zwei Fragen. Zunächst die Verständnisfrage:
In nachfolgendem Programm erstelle ich zwei JFrames, einer ist als Auswahlmenü gedacht, der andere als Zeichentafel.
Verwende ich im MouseListener der Klasse Tafel bzw. des darauf liegenden JPanels, update(), funktioniert alles normal. Verwende ich dagegen repaint(), erscheint der Button der Klasse Auswahl zusätzlich im JFrame der Tafel. Spätestens dann wenn ich auf den Button "Pinsel" in der Auswahl klicke und dann wieder auf der Tafel male.
Ich verstehe nicht warum. Repaint() ruft doch auch nur update auf. Kann mir jemand erläutern was genau da abläuft?

Die andere Frage wäre: Ist es überhaupt eine gute Vorgehensweise mit zwei JFrames zu arbeiten? Oder ist davon prinzipiell abzuraten?

Eine JToolbar habe ich übrigens deswegen nicht genommen, weil ich die Toolbar von Anfang an separat haben will. Und nicht erst abkoppeln muss.

Freundliche Grüße,
Achim

Datei Start.java
Java:
package miniMalen1;

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

public class Start extends JFrame {

    public static void main(String[] a) {
        new Start();
    }

    public Start() {
        init();
    }

    private void init() {
        Tafel tafel = new Tafel();
        Auswahl auswahl = new Auswahl();
    }

}


Datei Auswahl.java
Java:
package miniMalen1;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;

public class Auswahl extends JFrame implements ActionListener {

    public Auswahl() {
        initialisiereObjekte();
    }

    private void initialisiereObjekte() {
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setAlwaysOnTop(true);
        this.setLayout(new FlowLayout());
        this.getContentPane().setBackground(Color.WHITE);
        this.setBounds(100, 100, 250, 250);
        this.setTitle("Auswahl");
        this.setBackground(Color.WHITE);

        JPanel p = new JPanel();
        p.setBounds(0, 0, 400, 400);
        p.setBackground(Color.white);
        p.setLayout(new FlowLayout());

        JToggleButton pinselBtn = new JToggleButton("Pinsel");
        pinselBtn.setBounds(0, 0, 100, 30);
        p.add(pinselBtn);

        this.add(p);

        sichtbar();

    }

    private void sichtbar() {
        this.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {

    }

}


Datei Tafel.java
Java:
package miniMalen1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Tafel extends JFrame {

    private JPanel panel;
    private int x = -10;
    private int y = -10;

    int pinseldicke = 1;

    public Tafel() {
        initialisiereTafel();
    }

    private void initialisiereTafel() {
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setBounds(0, 0, 500, 500);
        this.setLocationRelativeTo(null);
        this.setAlwaysOnTop(true);
        this.setBackground(Color.white);
        this.setTitle("Tafel");
        this.setLayout(null);

        sichtbar();

        panel = new JPanel() {

            public void paintComponent(Graphics g) {

                g.fillOval(x, y, 10, 10);

            }

        };

        panel.setBackground(Color.CYAN);

        panel.setBounds(0, 0, 500, 500);
        this.add(panel);

        panel.addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent arg0) {
                System.out.println("Dragged");
                x = arg0.getX();
                y = arg0.getY();
                Graphics gr = panel.getGraphics();
                panel.update(gr);
                // panel.repaint();
            }
        });
       
        panel.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent arg0) {
                System.out.println("Test");
                x = arg0.getX();
                y = arg0.getY();
                Graphics gr = panel.getGraphics();
                panel.update(gr);
                // panel.repaint();
            }
        });
       
    }

    private void sichtbar() {
        this.setVisible(true);

    }

}
 
Stimmt, danke für den Hinweis, auf das extends JFrame in Start kann ich natürlich verzichten.
Problem ist nur, das der Fehler sowohl mit JDialog also auch mit JWindow auftritt.
Wie gesagt, der Fehler tritt nur auf, wenn ich repaint() statt update() verwende..
 
Unten nochmals der Code etwas übersichtlicher. Auch verwende ich jetzt im zweiten Fenster JDialog. Der Fehler müsste sofort nach dem Malen auftreten. Kann jemand den Fehler reproduzieren?
Habe mit Java 1.8.0_191 getestet.

Java:
package miniMalen1;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainWindow extends JFrame {
 
    private int x = -10;
    private int y = -10;

    public static void main(String[] args) {
        MainWindow window1 = new MainWindow();
        SecondWindow window2 = new SecondWindow();
        window2.setLocationRelativeTo(window1);
        window2.setBounds(100, 100, 200, 200);
    }
 
    public MainWindow() {
        init();
    }

    private void init() {
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setBounds(0, 0, 500, 500);
        this.setLocationRelativeTo(null);
        this.setAlwaysOnTop(true);
        this.setBackground(Color.white);
        this.setLayout(null);
        this.setVisible(true);
     
        JPanel panel = new JPanel() {
            public void paintComponent(Graphics g) {
                g.fillOval(x, y, 10, 10);
            }
        };

        panel.setBackground(Color.WHITE);
        panel.setBounds(0, 0, 500, 500);
        this.add(panel);

        panel.addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent arg0) {
                x = arg0.getX();
                y = arg0.getY();
//                Graphics g = panel.getGraphics();
//                panel.update(g); // mit update() tretet der Fehler nicht auf
                panel.repaint(); // hier tretet der Fehler auf.
            }
        });
     
        panel.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent arg0) {
                x = arg0.getX();
                y = arg0.getY();
//                Graphics g = panel.getGraphics();
//                panel.update(g); // Mit update() tretet der Fehler nicht auf.
                panel.repaint(); // hier tretet der Fehler auf.
            }
        });
    }
}

class SecondWindow extends JDialog {
 
    public SecondWindow() {
        this.setDefaultCloseOperation(HIDE_ON_CLOSE);
        this.setAlwaysOnTop(true);
        this.setBackground(Color.white);
        this.setLayout(null);
     
        init();
    }

    private void init() {
        JButton button = new JButton("Button");
        button.setBounds(0, 0, 100, 30);
        this.add(button);     
     
        this.setVisible(true);
    }
 
}
 

Zurück
Oben