Forum: PC-Programmierung Java Swing: GUI Fehler unter Windows


von JavaNeuling (Gast)


Angehängte Dateien:

Lesenswert?

Für eine Übung habe ich ein Testprogramm geschrieben (Code anbei), 
welches auf Komponenten von Swing (JFrame, JPanel und JScrollBar) 
beruht. Geschrieben mit Eclipse 2019 auf dem Mac und als Jar-File 
exportiert.

Unter OSX sieht die GUI genau so aus, wie es gewollt ist und wie es m.E. 
auch im Code steht. Starte ich das gleiche Programm jedoch unter Windows 
10, sieht es bereits nach dem Start nicht exakt aus und fasst man dann 
einen der Scrollbalken an, erscheinen in der oberen linken Ecke 
"Fragmente" des selben.

Wer Lust und Zeit hat, bitte mal auf den Code sehen und mir mitteilen, 
wo der Fehler ist. Bitte keine Antworten, die eine völlig andere 
Herangehensweise an die Programmierung vorschlagen, ich möchte unbedingt 
wissen, wo genau der Fehler in konkret diesem Code ist. Danke.
1
import java.awt.BorderLayout;
2
import java.awt.event.AdjustmentEvent;
3
import java.awt.event.AdjustmentListener;
4
import javax.swing.border.BevelBorder;
5
import javax.swing.*;
6
import javax.swing.JScrollBar;
7
import java.awt.Graphics;
8
import java.awt.Color;
9
10
class gPanel extends JPanel
11
{
12
 
13
 private int cr=0;
14
 private int cg=0;
15
 private int cb=0;
16
 
17
 public void setRed(int r) {cr=r;}
18
 public void setGrn(int g) {cg=g;}
19
 public void setBlu(int b) {cb=b;}
20
 
21
 public void paint(Graphics g)
22
 {
23
  g.setColor(new Color(cr,cg,cb));
24
  g.fillRect(10, 10, 380, 30);
25
 }
26
27
}
28
29
public class CTest
30
{
31
 
32
  static gPanel cPanel;
33
  static JPanel  sPanel;
34
  static JLabel  rLabel, gLabel, bLabel;
35
  
36
  public static void winPlace(JFrame j, int x, int y, int w, int h)
37
  {
38
      j.setLayout(null);
39
      j.setLocation(x,y);
40
      j.setSize(w, h);       
41
  }
42
  
43
  public static void panPlace(JPanel j, int x, int y, int w, int h, Color c)
44
  {
45
      j.setLayout(null);
46
      j.setLocation(x,y);
47
      j.setSize(w, h);   
48
      j.setBackground(c);
49
  }
50
  
51
  public static void main(String args[])
52
  {
53
    
54
   AdjustmentListener rList = new AdjustmentListener()
55
   {
56
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
57
    {
58
     int rVol = 255-adjustmentEvent.getValue();
59
     rLabel.setText(""+rVol);
60
     cPanel.setRed(rVol);
61
     cPanel.repaint();
62
     
63
    }
64
   };
65
   
66
   AdjustmentListener gList = new AdjustmentListener()
67
   {
68
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
69
    {
70
     int gVol = 255-adjustmentEvent.getValue();
71
     gLabel.setText(""+gVol);
72
     cPanel.setGrn(255-adjustmentEvent.getValue());
73
     cPanel.repaint();
74
    }
75
   };
76
   
77
   AdjustmentListener bList = new AdjustmentListener()
78
   {
79
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
80
    {
81
     int bVol = 255-adjustmentEvent.getValue();
82
     bLabel.setText(""+bVol);
83
     cPanel.setBlu(255-adjustmentEvent.getValue());
84
     cPanel.repaint();
85
    }
86
   };
87
     
88
      JFrame myWin = new JFrame();        
89
      myWin.setTitle("JScrollBar Beispiel");
90
      myWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
91
      winPlace(myWin,400,400,400,400);
92
      
93
      cPanel = new gPanel();
94
      panPlace(cPanel,0,0,400,50,Color.gray);
95
      myWin.add(cPanel);
96
      
97
      sPanel = new JPanel();
98
      panPlace(sPanel,0,55,400,330,Color.yellow);
99
      myWin.add(sPanel);
100
      
101
      JScrollBar rScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
102
      rScroll.setBounds(30,30,20,255);
103
      rScroll.setBorder(BorderFactory.createLineBorder(Color.red,2));
104
      rScroll.addAdjustmentListener(rList);
105
      sPanel.add(rScroll);
106
      
107
      rLabel = new JLabel("0");
108
      rLabel.setBounds(30,10,30,20);
109
      sPanel.add(rLabel);
110
      
111
      JScrollBar gScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
112
      gScroll.setBounds(90,30,20,255);
113
      gScroll.setBorder(BorderFactory.createLineBorder(Color.green,2));
114
      gScroll.addAdjustmentListener(gList);
115
      sPanel.add(gScroll);
116
      
117
      gLabel = new JLabel("0");
118
      gLabel.setBounds(90,10,30,20);
119
      sPanel.add(gLabel);
120
      
121
      JScrollBar bScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
122
      bScroll.setBounds(150,30,20,255);
123
      bScroll.setBorder(BorderFactory.createLineBorder(Color.blue,2));
124
      bScroll.addAdjustmentListener(bList);
125
      sPanel.add(bScroll);
126
      
127
      bLabel = new JLabel("0");
128
      bLabel.setBounds(150,10,30,20);
129
      sPanel.add(bLabel);
130
      
131
      myWin.setVisible(true);
132
      cPanel.repaint(); 
133
  }
134
}

von JavaNeuling (Gast)


Lesenswert?

Nachtrag: Was mich auch wundert: Es sollte doch genügen, wenn ich z.B.:

import javax.swing.*;

schreibe. Aber es gibt immer wieder einzelne Klassen aus Swing, die 
müssen unbedingt explitit aufgerufen werden, sinst "kotzt" Eclipse. 
Warum? Bug oder unverstandenes Feature? Bei awt ist das noch viel 
schlimmer ...

von Andreas B. (andreasb)


Lesenswert?

JavaNeuling schrieb:
> Nachtrag: Was mich auch wundert: Es sollte doch genügen, wenn ich z.B.:
>
> import javax.swing.*;
Das ist NICHT rekursiv.

Dein eigentliches Problem:
1
 public void paint(Graphics g)
2
 {
3
  g.setColor(new Color(cr,cg,cb));
4
  g.fillRect(10, 10, 380, 30);
5
 }

Du zeichnest hier nur ein Teil des Panel.
Mach auf der 1. Zeile noch super.paint(g);

Der würde den Hintergrund zeichnen.

Jetzt wird nur dieses Rechteck gezeichnet, alles andere ist einfach 
Zufall.
Und Zufall ist Betriebsystem Abhängig.

mfg Andreas

: Bearbeitet durch User
von JavaNeuling (Gast)


Lesenswert?

Andreas B. schrieb:

> Dein eigentliches Problem: public void paint(Graphics g)
>  {
>   g.setColor(new Color(cr,cg,cb));
>   g.fillRect(10, 10, 380, 30);
>  }
>
> Du zeichnest hier nur ein Teil des Panel.
> Mach auf der 1. Zeile noch super.paint(g);


Hmmm ... OK, danke. Das Einfügen dieser Zeile verhindert, dass ich den 
"Unfall" in der Ecke zu sehen bekomme, weil er schnell übermalt wird - 
soweit so gut.

Aber wieso werden dort oben überhaupt Fragmente der Scrollbars 
hingezeichnet? Die "kleben" doch ganz eindeutig an sPanel, ganz 
definiert mit SetBounds ... ?

Beitrag #6003746 wurde vom Autor gelöscht.
von Franko S. (frank_s866)


Lesenswert?

JavaNeuling schrieb:
> Aber wieso werden dort oben überhaupt Fragmente der Scrollbars
> hingezeichnet? Die "kleben" doch ganz eindeutig an sPanel, ganz
> definiert mit SetBounds ... ?

Dein LayoutManger ist auf null gesetzt, da musst du dann selber z.t. für 
repaints sorgen, evt. auf den EDT warten,.... Das lässt man deshalb 
immer bleiben ausser du machst Animationen,... wo das eher wieder stört 
wenn der dazwischen funkt.

Wenn du das ohne LM machst musst du selber für den Repaint sorgen, 
teilweise spielt es glaube ich noch eine Rolle wie der Background der 
Komponente gesetzt ist, opaque oder nicht, da hat man auch entspr. 
Effekte wobei das bei dir der Nulllayout ist.

von JavaNeuling (Gast)


Lesenswert?

Franko S. schrieb:
> JavaNeuling schrieb:
>> Aber wieso werden dort oben überhaupt Fragmente der Scrollbars
>> hingezeichnet? Die "kleben" doch ganz eindeutig an sPanel, ganz
>> definiert mit SetBounds ... ?
>
> Dein LayoutManger ist auf null gesetzt, da musst du dann selber z.t. für
> repaints sorgen, evt. auf den EDT warten,.... Das lässt man deshalb
> immer bleiben ausser du machst Animationen,... wo das eher wieder stört
> wenn der dazwischen funkt.

Den Layoumanager habe ich auf Null gesetzt, weil der sonst bestimmt, wo 
die Controls stehen und setBounds() bzw. setLocation() für die Panele 
keine Wirkung haben. Gibt es da eine "Zwischenlösung"?

von Andreas B. (andreasb)


Lesenswert?

JavaNeuling schrieb:
> Den Layoumanager habe ich auf Null gesetzt, weil der sonst bestimmt, wo
> die Controls stehen und setBounds() bzw. setLocation() für die Panele
> keine Wirkung haben. Gibt es da eine "Zwischenlösung"?

Du kannst einen eignen LayoutManager machen, für Spezialfälle ist das 
oft recht angenehm.
Aber grundsätzlich sind die Layoutmanager schon das richtige.
Denk mal z.B. dran, das jemand schlecht sieht, und die Schrift doppelt 
so gross eingestellt hat wie du.

Dann passt der Text nicht mehr in den Label. Bei Layoutmanger passiert 
das nicht, da wird halt das Fenster grosser...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.