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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von JavaNeuling (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.
import java.awt.BorderLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.border.BevelBorder;
import javax.swing.*;
import javax.swing.JScrollBar;
import java.awt.Graphics;
import java.awt.Color;

class gPanel extends JPanel
{
 
 private int cr=0;
 private int cg=0;
 private int cb=0;
 
 public void setRed(int r) {cr=r;}
 public void setGrn(int g) {cg=g;}
 public void setBlu(int b) {cb=b;}
 
 public void paint(Graphics g)
 {
  g.setColor(new Color(cr,cg,cb));
  g.fillRect(10, 10, 380, 30);
 }

}

public class CTest
{
 
  static gPanel cPanel;
  static JPanel  sPanel;
  static JLabel  rLabel, gLabel, bLabel;
  
  public static void winPlace(JFrame j, int x, int y, int w, int h)
  {
      j.setLayout(null);
      j.setLocation(x,y);
      j.setSize(w, h);       
  }
  
  public static void panPlace(JPanel j, int x, int y, int w, int h, Color c)
  {
      j.setLayout(null);
      j.setLocation(x,y);
      j.setSize(w, h);   
      j.setBackground(c);
  }
  
  public static void main(String args[])
  {
    
   AdjustmentListener rList = new AdjustmentListener()
   {
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
    {
     int rVol = 255-adjustmentEvent.getValue();
     rLabel.setText(""+rVol);
     cPanel.setRed(rVol);
     cPanel.repaint();
     
    }
   };
   
   AdjustmentListener gList = new AdjustmentListener()
   {
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
    {
     int gVol = 255-adjustmentEvent.getValue();
     gLabel.setText(""+gVol);
     cPanel.setGrn(255-adjustmentEvent.getValue());
     cPanel.repaint();
    }
   };
   
   AdjustmentListener bList = new AdjustmentListener()
   {
    public void adjustmentValueChanged(AdjustmentEvent adjustmentEvent)
    {
     int bVol = 255-adjustmentEvent.getValue();
     bLabel.setText(""+bVol);
     cPanel.setBlu(255-adjustmentEvent.getValue());
     cPanel.repaint();
    }
   };
     
      JFrame myWin = new JFrame();        
      myWin.setTitle("JScrollBar Beispiel");
      myWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      winPlace(myWin,400,400,400,400);
      
      cPanel = new gPanel();
      panPlace(cPanel,0,0,400,50,Color.gray);
      myWin.add(cPanel);
      
      sPanel = new JPanel();
      panPlace(sPanel,0,55,400,330,Color.yellow);
      myWin.add(sPanel);
      
      JScrollBar rScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
      rScroll.setBounds(30,30,20,255);
      rScroll.setBorder(BorderFactory.createLineBorder(Color.red,2));
      rScroll.addAdjustmentListener(rList);
      sPanel.add(rScroll);
      
      rLabel = new JLabel("0");
      rLabel.setBounds(30,10,30,20);
      sPanel.add(rLabel);
      
      JScrollBar gScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
      gScroll.setBounds(90,30,20,255);
      gScroll.setBorder(BorderFactory.createLineBorder(Color.green,2));
      gScroll.addAdjustmentListener(gList);
      sPanel.add(gScroll);
      
      gLabel = new JLabel("0");
      gLabel.setBounds(90,10,30,20);
      sPanel.add(gLabel);
      
      JScrollBar bScroll = new JScrollBar(JScrollBar.VERTICAL, 255, 0, 0, 255);
      bScroll.setBounds(150,30,20,255);
      bScroll.setBorder(BorderFactory.createLineBorder(Color.blue,2));
      bScroll.addAdjustmentListener(bList);
      sPanel.add(bScroll);
      
      bLabel = new JLabel("0");
      bLabel.setBounds(150,10,30,20);
      sPanel.add(bLabel);
      
      myWin.setVisible(true);
      cPanel.repaint(); 
  }
}

von JavaNeuling (Gast)


Bewertung
0 lesenswert
nicht 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)


Bewertung
2 lesenswert
nicht 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:
 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);

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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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)


Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.