2016-12-20 2 views
1

Ich versuche ein scrollbares Panel mit Swing zu erstellen. Aber da ich neu bin zu schwingen, versage ich es. In meinem Code zeigt sich nichts in der jScrollablePane.Java Swing - Scrollbares Panel

habe ich erstellt eine JFrame und legte eine jScrollablePane in seinem Inneren. Und ich erstellte eine Klasse namens UIElement, die jPanel erweitert, die einen Komponentenabschnitt und untergeordneten Abschnitt enthält. Kind Abschnitte bestehen aus anderen UIElement s.

  • All UIElements sollte unter der vorherige UIElement platziert werden. Wie eine vertikale Liste.
  • Die Kinder sollte unter Komponenten platziert werden.
  • Der Abschnitt Childs kann nicht gescrollt werden, und seine Höhe ist auf die Gesamtgröße der untergeordneten UIElements festgelegt.
  • Die Komponenten hat eine feste Höhe von 40. Während die Breite mit seinem Container erweitern konnte.
  • Die Spacer ‚s Breite dynamisch
  • Ausnahme von Spacer, Breite der alles bis 40 festgelegt werden sollte.
  • Ein UIElement könnte null oder mehr Kinder haben.

Hier ist ein Bildbeispiel, nicht vergessen: Breite ist dynamisch.

enter image description here

Und hier ist der Code:

public static void scrollable(String title) { 
    //Create and set up the window. 
    JFrame frame = new JFrame(title); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setSize(500,GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height); 

    JPanel mainPanel = new JPanel(); 
    mainPanel.setLayout(new BoxLayout(mainPanel,BoxLayout.Y_AXIS)); 
    mainPanel.setBackground(Color.WHITE); 

    mainPanel.add(new UIElement()); 

    JScrollPane scrollPane = new JScrollPane(mainPanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
    frame.getContentPane().add(scrollPane); 

    //Display the window. 
    frame.setVisible(true); 
} 

Und hier ist die UIElement Klasse:

public abstract class UIElement extends JPanel { 
    public static final int DESIREDHEIGHT = 40; 

    JPanel componentsPanel, childPanel; 

    public UIElement() { 
     super(); 
     this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 
     this.setBackground(Color.BLACK); 

     // componentsPanel 
     componentsPanel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       Dimension d = super.getMaximumSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 
     }; 
     componentsPanel.setLayout(new BoxLayout(componentsPanel,BoxLayout.X_AXIS)); 
     componentsPanel.setBackground(Color.BLUE); 
     this.add(componentsPanel); 

     // child panel 
     childPanel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getPreferredSize().height; 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getMaximumSize().height; 
       Dimension d = super.getMaximumSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getMinimumSize().height; 
       Dimension d = super.getMinimumSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 
     }; 
     childPanel.setLayout(new BoxLayout(childPanel,BoxLayout.Y_AXIS)); 
     childPanel.setBackground(Color.RED); 

     // parent for childPanel and spacer 
     JPanel childParent = new JPanel(); 
     childParent.setLayout(new BoxLayout(childParent,BoxLayout.X_AXIS)); 

     // spacer 
     JPanel spacer = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 
     }; 
     spacer.setBackground(Color.RED); 
     childParent.add(spacer); 
     // add the childPanel later 
     childParent.add(childPanel); 
    } 


    @Override 
    public Dimension getPreferredSize() { 
     Dimension c = componentsPanel.getPreferredSize(); 
     Dimension d = childPanel.getPreferredSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

    @Override 
    public Dimension getMaximumSize() { 
     Dimension c = componentsPanel.getMaximumSize(); 
     Dimension d = childPanel.getMaximumSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

    @Override 
    public Dimension getMinimumSize() { 
     Dimension c = componentsPanel.getMinimumSize(); 
     Dimension d = childPanel.getMinimumSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

} 

Antwort

1

nicht außer Kraft getPreferredSize() (oder maximal/minim Größen) der Paneele.

Jedes Panel bestimmt seine bevorzugte Größe basierend auf dem Layout-Manager des Panels und den Komponenten, die dem Panel hinzugefügt werden.

Wenn ein Panel einen Layout-Manager verwendet, müssen diese Methoden nicht überschrieben werden. Sie müssen nur die Methoden getPreferredSize() für eine benutzerdefinierte Komponente überschreiben, die keinen Layout-Manager hat. In Swing-Begriffen wäre dies ein JButton, JTextField, JLabel usw.

Also wenn Sie eine benutzerdefinierte Komponente erstellen, dann legen Sie die Größe fest. Wenn Sie eine Komponente nur als Container mit einem Layout-Manager verwenden, um andere Komponenten aufzunehmen, berechnen Sie die Größe nicht.

+0

https://docs.oracle.com/javase/tutorial/uiswing/layout/problems.html - Suche nach dem Wort "fix" – ossobuko

+0

löschte alle Überschreibungen für die getPreferredSize() -Methode, hat nicht funktioniert – ossobuko

+0

@ossobuko, Sie haben meinen Punkt über die "benutzerdefinierten Komponenten", die eine richtige Größe definiert haben müssen, verpasst. Wenn Sie nur JPanels verwenden, dann benötigt das benutzerdefinierte Feld am unteren Ende der Hierarchie die richtige Größe. Die Felder in der Mitte der Hierarchie, die mir erscheinen, als ob sie ein BoxLayout verwenden, sollten die Größenberechnungen NICHT überschreiben. – camickr