2012-06-13 14 views
5

Ho cercato per ore di trovare un modo per risolvere il problema, ma non ho avuto fortuna con quello. Ecco un esempio di codice:JScrollPane non appare quando lo si utilizza su 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

Invece di usare 'BoxLayout', provate' GridLayout', come mostrato in questo [esempio] (http://stackoverflow.com/questions/10331129/jscrollpane-resize-contain-jpanel-when-scrollbars-appear/ 10333957 # 10333957), Poiché in 'GridLayout' tutti i' JButton's avranno dimensioni uguali, diversamente da 'BoxLayout', dove la dimensione è determinata dal testo al suo interno. –

risposta

7

Devo sempre impostare la dimensione preferita della finestra come questa.

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

Puoi anche implementare 'Scrollable'. – trashgod

3

È necessario impostare la preferita di dimensioni, nel caso in cui JScrollPane è unico JComponent nel contenitore o di livello superiore contenitore.

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

migliore sarebbe quella di utilizzare GridLayout per lo stesso tipo di JComponent s.

+0

Ma quando lo faccio, 'panTopCenter' avrà una dimensione statica e non si ingrandirà dinamicamente dopo aver ingrandito la dimensione JFrame. –

+0

[questo potrebbe essere il modo giusto] (http://stackoverflow.com/a/5760093/714968) – mKorbel

+0

Penso che tu possa cambiare la dimensione del viewport come [here] (http://stackoverflow.com/a/11016543/ 261.156). –

7

Non impostare alcuna dimensione! La barra di scorrimento viene visualizzata se viene apportata questa modifica.

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

Il problema di fondo è che FlowLayout mostrerà componenti alla più piccola dimensione necessaria per visualizzare, e per un rotolo-pane, che è (ha deciso di essere) 0x0. Usando un GridLayout senza argomenti nel costruttore e aggiungendo il riquadro di scorrimento come unico componente, sarà costretto a riempire lo spazio disponibile.

+1

+1 IIUC, il problema è che la dimensione preferita della viewport risultante è ingombrante e (possibilmente) dipendente da L & F. Vorrei sostenere l'implementazione di 'getPreferredScrollableViewportSize()'. – trashgod

+0

@trashgod Riesco a vedere situazioni in cui potrebbe essere necessaria l'impostazione di una dimensione di porta di visualizzazione preferita, ma sono sempre molto cauto riguardo a "impostare ** qualsiasi ** dimensione". È qualcosa a cui tengo solo, dopo aver esaurito altre probabili possibilità. –

+0

@both ammetto, non capisco molto bene questa domanda +1 per la risposta corretta forse – mKorbel

0

La soluzione migliore, semplice e veloce, utilizza JXPanel da SwingX, che è quasi standard e implementa Scrollable.

Problemi correlati