2017-01-13 9 views
1

Ich hatte keine Ahnung, ob das Problem, das ich konfrontiert bin, nur für meine Situation, so schrieb ich eine abgespeckte Version von was mein Problem verursacht (mit JLabel s als Beispielkomponente).Fix Höhe von JScrollPane

public class InterestingBehavior { 

    static int direction = -4; 
    static final boolean useScroll = true; 
    static final String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
              + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 

    public static void main(String[] args) { 
     JFrame test = new JFrame("Test"); 
     test.setSize(500, 300); 
     test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     test.setLayout(new BoxLayout(test.getContentPane(), BoxLayout.Y_AXIS)); 
     for (int i = 0; i < 10; i++) 
      test.add(useScroll ? new JScrollPane(new JLabel(longString)) : new JLabel(longString)); 
     test.add(Box.createVerticalGlue()); //should use all available space 

     final int min = 300, max = 600; 
     new Timer(50, e -> { 
      int h = test.getHeight(); 
      SwingUtilities.invokeLater(() -> test.setSize(test.getWidth(), h + direction)); 
      direction = h == min || h == max ? -direction : direction; 
     }).start(); 

     test.setVisible(true); 
    } 

} 

Der Rahmen ändert sich selbst, um zu zeigen, was ich will/will nicht. Hinzufügen JLabel s zu BoxLayout hält sie alle an der Spitze der JFrame - das ist, was ich will, weil ich vertikale Leim auf der Platte hinzugefügt. Wenn ich jedoch die JLabel in eine JScrollPane wrap, entscheidet es sich automatisch die Größe automatisch auf der Höhe der JFrame - Wie vermeide ich dieses Verhalten und halten Sie den Bildlaufbereich auf einer konstanten Höhe?

Der Rahmen:

expanded scroll pane

wenn die Größe verändert wird

small pane

, die nicht das, was ich will.

Wie kann ich eine Dimension genau an die der untergeordneten Komponente (Ansichtsfenster) anpassen?

Antwort

1

Das Problem ist, dass JScrollPane sich den gesamten Platz ergreift, den es bekommt. Der BoxLayout verteilt den verfügbaren Abstand zwischen den JScrollPanes und dem vertikalen Kleber ziemlich gleichmäßig.

Die Lösung besteht darin, den vertikalen Raum zu begrenzen, den das JScrollPanel unter Verwendung z.B. jScrollPane.setMaxmimumSize(new Dimension(1000, 50)).

Jetzt haben Sie jedes ScrollPane, das genau diesen Raum ergreift, der zu unheimlichem Verhalten führt, wenn die Größenänderung und tatsächlich die horizontale Scrollbar gemalt werden müssen. Daher möchten Sie vielleicht eine bevorzugte Größe haben, z.B. jScrollPane.setPreferredSize(new Dimension(0, 50)), auch.

das komplette Beispiel:

static int direction = -4; 
    static final boolean useScroll = true; 
    static final String longString = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
              + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 

    public static void main(String[] args) { 
     JFrame test = new JFrame("Test"); 
     test.setSize(500, 300); 
     test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     test.setLayout(new BoxLayout(test.getContentPane(), BoxLayout.Y_AXIS)); 
     for (int i = 0; i < 10; i++) { 
      if(useScroll) { 
       JScrollPane jScrollPane = new JScrollPane(new JLabel(longString)); 
       jScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
       jScrollPane.setMaximumSize(new Dimension(1000, 50)); 
       jScrollPane.setPreferredSize(new Dimension(0, 50)); 
       test.add(jScrollPane); 
      } else { 
       test.add(new JLabel(longString)); 
      } 
     } 
     test.add(Box.createVerticalGlue()); //should use all available space 

     final int min = 300, max = 600; 
     new Timer(50, e -> { 
      int h = test.getHeight(); 
      SwingUtilities.invokeLater(() -> test.setSize(test.getWidth(), h + direction)); 
      direction = h == min || h == max ? -direction : direction; 
     }).start(); 

     test.setVisible(true); 
    }