Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

1

25.09.2015, 12:36

Swing JFrame Grafikfehler

Moinsen,

Ich habe eine kleine sinnlose Swing Anwendung geschrieben, bei der aber ein Problem entstanden ist. Es funktioniert alles so wie es soll, ausser folgendes: Wenn ich auf einen der Buttons klicke, wird der Button oben links in der Ecke nochmal gezeichnet, was natürlich nicht passieren soll. Erst wenn ich die Grööße des Fensters ändere, verschwindet der Button.
Könnte bitte jemand von euch den Code mal bei sich ausführen um zu sehen, ob das dann auch so ist? Ich erwarte nämlich eigentlich dass das alles so richtig ist.


Hier mal der gesamte Code:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class CircleRect extends JFrame{
    public static void main(String[] args){
        CircleRect ksat = new CircleRect();
    }
    
    public CircleRect(){
        CirclePanel cp = new CirclePanel();
        Clistener cl = new Clistener(cp);
        JPanel pBot = new JPanel();
        
        this.setLayout(new GridLayout(2,1));
        
        cp.add(new JLabel("Hier stand irgendein Zeug"));
        
        JButton btnC = new JButton("Circle");
        btnC.setActionCommand("c");
        btnC.addActionListener(cl);
        pBot.add(btnC);
        JButton btnR = new JButton("Rechteck");
        btnR.setActionCommand("r");
        btnR.addActionListener(cl);
        pBot.add(btnR);
        
        add(cp);
        add(pBot);
        
        setVisible(true);
        setSize(400,250);
    }
}

class CirclePanel extends  JPanel{
    public boolean circle;
    public void paintComponent(Graphics g){
        g.setColor(Color.black);
        if(circle == true){
            g.drawOval(150,50,50,50);
        }
        else{
            g.drawRect(150,50,50,50);
        }
    }
}

class Clistener implements ActionListener{
    CirclePanel cP;
    Clistener(CirclePanel c){
        cP = c;
    }
    
    public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("c"))
            cP.circle = true;
        if(e.getActionCommand().equals("r"))
            cP.circle = false;
        cP.repaint();
    }
}


Um Schönheit oder Sinn geht es hier wirklich nicht, sondern nur um den Grafik Fehler. Und falls es bei euch klappt, weiss jemand woran es bei mir liegen könnte?
Danke schonmal im Voraus an den, der es testet :)

2

25.09.2015, 13:51

Eine schnelle Möglichkeit besteht darin, dass du auf das das ganze Frame ein Repaint aufrufst, also so:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    public CircleRect(){
        CirclePanel cp = new CirclePanel();
        Clistener cl = new Clistener(this, cp);
        JPanel pBot = new JPanel();


...
...
...



class Clistener implements ActionListener{
    CirclePanel cP;
    JFrame frame;
    Clistener(JFrame pFrame, CirclePanel c){
        cP = c;
        frame = pFrame;
    }
    
    public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("c"))
            cP.circle = true;
        if(e.getActionCommand().equals("r"))
            cP.circle = false;
        //cP.repaint();
        frame.repaint();
    }


Obs die schönste Variante ist, weiß ich nicht, aber sie funktioniert ;)

edit: geht natürlich uach mit
cP.getParent().repaint();

Tobiking

1x Rätselkönig

  • Private Nachricht senden

3

25.09.2015, 14:14

Ich denke das Problem liegt darin das JPanel per default auf opaque (nicht transparent) stehen, du aber in der paintComponent keinen Hintergrund zeichnest (kein super.paintComponent und kein eigener Hintergrund). Swing geht dann davon aus das der Bereich oben Links vom Frame nicht neu gezeichnet werden muss, da das Panel dann aber transparent ist, wird der Bereich sichtbar.

Repaint auf das Frame korrigiert zwar die Anzeige, aber besser wäre das Panel auf transparent zu stellen mit setOpaque(false) oder in der paintComponent super.paintComponent aufzurufen, damit der Hintergrund gezeichnet wird.

4

25.09.2015, 15:15

Zitat

Repaint auf das Frame korrigiert zwar die Anzeige, aber besser wäre das Panel auf transparent zu stellen mit setOpaque(false) oder in der paintComponent super.paintComponent aufzurufen, damit der Hintergrund gezeichnet wird.


Jetzt wo du das sagst, fällt mir ein, dass ich genau das Problem auch mal hatte, hatte es mit dem super.paintComponent gelöst ;) hast recht, das ist einiges eleganter :thumbup:

ERROR

Alter Hase

  • »ERROR« ist der Autor dieses Themas

Beiträge: 417

Wohnort: Paderborn

Beruf: Informatik Student

  • Private Nachricht senden

5

25.09.2015, 17:40

Danke für den Tipp, setOpaque(false); hat den Fehler behoben. Allerdings verstehe ich nicht, wieso plötzlich oben links die beiden Button nach dem ich drauf klicke auftauchen. Weil die Button werden eigentlich nur in der Mitte gezeichent. Bild zu Erklärung ist angehängt. Weil wenn nichts da ist, dürfte ja auch nichts sichtbar sein, ob es nun transparent ist oder nicht?
»ERROR« hat folgendes Bild angehängt:
  • jframe.PNG

Tobiking

1x Rätselkönig

  • Private Nachricht senden

6

25.09.2015, 19:29

Danke für den Tipp, setOpaque(false); hat den Fehler behoben. Allerdings verstehe ich nicht, wieso plötzlich oben links die beiden Button nach dem ich drauf klicke auftauchen. Weil die Button werden eigentlich nur in der Mitte gezeichent. Bild zu Erklärung ist angehängt. Weil wenn nichts da ist, dürfte ja auch nichts sichtbar sein, ob es nun transparent ist oder nicht?

Ich weiß nicht wie das intern genau abläuft. Möglicherweise nutzt Swing den Bereich um Komponenten zu zeichnen um dann nur das fertige Bild an die Endposition blitten zu müssen. Die Doku spricht da nur von screen garbage: http://www.oracle.com/technetwork/java/p…0037.html#props

Werbeanzeige