Java Swing: GUI Fehler unter Windows

Gast #6003478
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
}
Angehängte Dateien:
Gast #6003485
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 ...
#6003490
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
Gast #6003506
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 von einem Moderator gelöscht.
Gast #6003782
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.
Gast #6004111
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"?
#6004503
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...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren