2012-06-13 4 views
5

Ich habe seit Stunden versucht, einen Weg zu finden, um das Problem zu lösen, aber ich hatte kein Glück damit. Hier ist ein Beispielcode:JScrollPane erscheint nicht, wenn es auf einem JPanel verwendet

import java.awt.BorderLayout; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

public class Example extends JFrame 
{ 
    private static final long serialVersionUID = 1L; 

    public Example() 
    { 
     JPanel contentPane = (JPanel) getContentPane(); 
     contentPane.setLayout(new BorderLayout()); 

     JPanel panTop = new JPanel(new BorderLayout()); 
     //JPanel panBottom = new JPanel(new BorderLayout()); 

     JPanel panTopCenter = new JPanel(); 
     //JPanel panTopLeft = new JPanel(); 
     //JPanel panTopRight = new JPanel(); 

     panTop.add(panTopCenter, BorderLayout.CENTER); 
     //panTop.add(panTopLeft, BorderLayout.WEST); 
     //panTop.add(panTopRight, BorderLayout.EAST); 

     contentPane.add(panTop, BorderLayout.CENTER); 
     //contentPane.add(panBottom, BorderLayout.SOUTH); 

     JPanel pan = new JPanel(); 
     pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS)); 
     for(int i = 0; i < 50; i++) pan.add(new JButton("Button " + i)); 
     JScrollPane scrollPane = new JScrollPane(pan); 
     panTopCenter.add(scrollPane); 

     pack(); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     {   
      @Override 
      public void run() 
      { 
       new Example(); 
      } 
     }); 
    } 
} 

Snapshot:

enter image description here

+0

Anstatt "BoxLayout" zu verwenden, versuchen Sie 'GridLayout', wie in diesem [Beispiel] (http://stackoverflow.com/questions/10331129/jscrollpane-resize-containing-jpanel-when-scrollbars-appear/) 10333957 # 10333957), da in 'GridLayout' alle' JButton's von gleicher Größe sind, im Gegensatz zu 'BoxLayout', wo die Größe durch den darin enthaltenen Text bestimmt wird. –

Antwort

7

Ich muss immer die bevorzugte Größe des Ansichtsfensters so einstellen.

import java.awt.*; 
import javax.swing.*; 

public class Example extends JFrame { 

    public Example() { 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 

     Box box = new Box(BoxLayout.Y_AXIS); 
     for (int i = 0; i < 50; i++) { 
      box.add(new JButton("Button " + i)); 
     } 
     JScrollPane sp = new JScrollPane(box); 
     Dimension d = new Dimension(box.getComponent(0).getPreferredSize()); 
     sp.getVerticalScrollBar().setUnitIncrement(d.height); 
     d.height *= 10; // Show at least 10 buttons 
     sp.getViewport().setPreferredSize(d); 

     add(sp, BorderLayout.CENTER); 
     pack(); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       Example e = new Example(); 
      } 
     }); 
    } 
} 
+2

Sie können auch 'Scrollable' implementieren. – trashgod

3

Sie haben die bevorzugte Größe zu setzen, in dem Fall, dass JScrollPane Single ist JComponent in dem Behälter oder der obersten Ebene Container.

scrollPane.setPreferredSize(new Dimension(100,500)); 

Besser wäre GridLayout für die gleiche Art von JComponent s zu verwenden.

+0

Aber wenn ich das mache, wird 'panTopCenter' eine statische Größe haben und wird nicht dynamisch vergrößert, wenn die JFrame Größe vergrößert wird. –

+0

[dann könnte dies der richtige Weg sein] (http://Stackoverflow.com/a/5760093/714968) – mKorbel

+0

Ich denke, dass Sie die Größe des Ansichtsfensters wie [hier] ändern können (http://Stackoverflow.com/a/11016543/ 261156). –

7

Stellen Sie keine Größen ein! Die Bildlaufleiste erscheint, wenn diese Änderung vorgenommen wird.

JPanel panTopCenter = new JPanel(new GridLayout()); 

Das grundlegende Problem ist, dass FlowLayout Komponenten bei der kleinsten Größe zeigen benötigt, um sie anzuzeigen, und für einen Spiralscheibe, dh (entschieden zu sein) 0x0. Wenn Sie GridLayout ohne Argumente im Konstruktor verwenden und den Bildlaufbereich als einzige Komponente hinzufügen, wird er gezwungen, den verfügbaren Platz zu füllen.

+1

+1 IIUC, das Problem ist, dass die resultierende Ansichtsfenster bevorzugte Größe ist unhandlich und (möglicherweise) L & F abhängig. Ich würde empfehlen, 'getPreferredScrollableViewportSize()' zu implementieren. – trashgod

+0

@trashgod Ich kann sehen, Situationen, in denen eine bevorzugte Ansicht Portgröße erforderlich sein kann, aber bin immer sehr vorsichtig über 'set ** any ** Größe'. Es ist etwas, auf das ich nur schaue, nachdem andere wahrscheinliche Möglichkeiten erschöpft sind. –

+0

@both Ich gebe zu, verstehe ich nicht sehr gut diese Frage +1 für vielleicht richtige Antwort – mKorbel

0

Die beste Lösung, schnell und einfach, verwendet JXPanel von SwingX, die Quasi-Standard ist und implementiert Scrollable.