2012-06-13 20 views
5

He estado tratando durante horas para encontrar una manera de resolver el problema, pero no tuve suerte con eso. Aquí está un ejemplo de código:JScrollPane no aparece cuando se usa en un JPanel

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

En lugar de usar 'BoxLayout', intente' GridLayout', como se muestra en este [ejemplo] (http://stackoverflow.com/questions/10331129/jscrollpane-resize-containing-jpanel-when-scrollbars-appear/ 10333957 # 10333957), ya que en 'GridLayout' todos los' JButton's serán de igual tamaño, a diferencia de 'BoxLayout', donde el tamaño del texto está determinado por el texto. –

Respuesta

7

Siempre tengo que establecer el tamaño preferido de la vista de esta manera.

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

También puede implementar 'Scrollable'. – trashgod

3

Usted tiene que fijar el tamaño preferido, en el caso de que JScrollPane es solo JComponent en el recipiente o de nivel superior envase.

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

mejor sería utilizar GridLayout para el mismo tipo de JComponent s.

+0

Pero cuando lo hago, 'panTopCenter' tendrá un tamaño estático y no se ampliará dinámicamente al ampliar el tamaño del JFrame. –

+0

[entonces esta podría ser la manera correcta] (http://stackoverflow.com/a/5760093/714968) – mKorbel

+0

Creo que puede cambiar el tamaño de la ventana gráfica como [aquí] (http://stackoverflow.com/a/11016543/ 261156). –

7

¡No configure ningún tamaño! La barra de desplazamiento aparece si se realiza este cambio.

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

El problema básico es que FlowLayout mostrará componentes en el tamaño más pequeño sea necesario para mostrarla, y por un desplazamiento de una ventana, que es (decidió ser) 0x0. Al usar GridLayout sin argumentos en el constructor y agregar el panel de desplazamiento como el único componente, se verá obligado a llenar el espacio disponible.

+1

+1 IIUC, el problema es que el tamaño preferido de ventana gráfica resultante es difícil de manejar y (posiblemente) dependiente de L & F. Yo recomendaría implementar 'getPreferredScrollableViewportSize()'. – trashgod

+0

@trashgod Puedo ver situaciones en las que puede ser necesario establecer un tamaño de puerto de vista preferido, pero siempre tengo mucho cuidado con 'establecer ** cualquier ** tamaño'. Es algo que solo busco, después de agotar otras posibilidades probables. –

+0

@both Lo admito, no entiendo muy bien esta pregunta +1 para tal vez la respuesta correcta – mKorbel

0

La mejor solución, rápida y fácil, es usar JXPanel de SwingX, que es casi estándar e implementa Scrollable.

Cuestiones relacionadas