2011-02-09 13 views
12

Il contenuto ridimensionabile di JScrollPane ha una larghezza minima. Se il JScrollPane è più piccolo di questa larghezza, dovrebbero apparire le barre di scorrimento orizzontali. Se è maggiore di questa larghezza, il contenuto della vista dovrebbe espandersi per riempire l'intera finestra.Ridimensionamento JScrollpane con contenuto di dimensioni variabili

sembra un concetto semplice, e ho qualcosa che sta lavorando, ma ci si sente come un hack:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ComponentAdapter; 
import java.awt.event.ComponentEvent; 

public class SSBTest { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       final Component view = new MyView(); 
       final JScrollPane jScrollPane = new JScrollPane(view); 
       jScrollPane.addComponentListener(new ComponentAdapter() { 
        @Override 
        public void componentResized(final ComponentEvent e) { 
         final Dimension minimumSize = view.getMinimumSize(); 
         final int width = Math.max(minimumSize.width, jScrollPane.getViewport().getWidth()); 
         view.setPreferredSize(new Dimension(width, minimumSize.height)); 
        } 
       }); 
       showInDialog(jScrollPane); 
      } 
     }); 
    } 

    private static void showInDialog(final JScrollPane jScrollPane) { 
     final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test"); 
     dialog.setResizable(true); 
     dialog.setModal(true); 
     dialog.setVisible(true); 
     System.exit(0); 
    } 

    private static final class MyView extends JPanel { 
     @Override 
     protected void paintComponent(final Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.RED); 
      g.drawString("Dimensions are " + getSize(), 10, 20); 
      g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1); 
      g.setColor(Color.BLUE); 
      g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1); 
     } 

     @Override 
     public Dimension getMinimumSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return super.getPreferredSize(); 
     } 
    } 
} 

Ridimensionare la finestra attiva il ComponentListener, che definisce esplicitamente la dimensione preferita della vista finestra , innescando la convalida del componente. Tuttavia, il ridimensionamento causa barre di scorrimento nervose. C'è un modo più pulito per fare questo?

EDIT: grazie alla camickr per il link ScrollablePanel, ho modificato la mia classe JPanel per implementare scorrevole, e dinamicamente modificare il valore di ritorno per getScrollableTracksViewportWidth().

Quando il viewport è grande, restituisco true per getScrollableTracksViewportWidth(), dicendo a JScrollPane di riempire la vista con il mio componente. Quando il viewport è piccolo, restituisco false, quindi vengono visualizzate le barre di scorrimento.

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

public class SSBTest { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       final Component view = new MyView(); 
       final JScrollPane jScrollPane = new JScrollPane(view); 
       showInDialog(jScrollPane); 
      } 
     }); 
    } 

    private static void showInDialog(final JScrollPane jScrollPane) { 
     final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test"); 
     dialog.setResizable(true); 
     dialog.setModal(true); 
     dialog.setVisible(true); 
     System.exit(0); 
    } 

    private static final class MyView extends JPanel implements Scrollable { 
     @Override 
     protected void paintComponent(final Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.RED); 
      g.drawString("MyView: " + getWidth() + "x" + getHeight(), 10, 20); 
      g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1); 
      g.setColor(Color.BLUE); 
      g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1); 
      g.drawString("Preferred/Minimum Size", 10, getPreferredSize().height/2); 
      g.setColor(Color.GREEN); 
      g.drawLine(0, 0, getWidth(), getHeight()); 
     } 

     @Override 
     public Dimension getMinimumSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return getMinimumSize(); 
     } 

     public Dimension getPreferredScrollableViewportSize() { 
      return getPreferredSize(); 
     } 

     public int getScrollableUnitIncrement(final Rectangle visibleRect, final int orientation, final int direction) { 
      return 10; 
     } 

     public int getScrollableBlockIncrement(final Rectangle visibleRect, final int orientation, final int direction) { 
      return visibleRect.width; 
     } 

     public boolean getScrollableTracksViewportWidth() { 
      final Container viewport = getParent(); 
      return viewport.getWidth() > getMinimumSize().width; 
     } 

     public boolean getScrollableTracksViewportHeight() { 
      return true; 
     } 

    } 
} 

risposta

7

Non è sicuro, ma si potrebbe essere in grado di utilizzare il Scrollable Panel. È possibile configurare il ridimensionamento del componente (provare a utilizzare STRETCH). Il codice funziona sulla dimensione preferita del componente, non sulla dimensione minima, quindi potrebbe non essere esattamente quello che desideri.

+1

Perfetto! Non sto utilizzando la classe ScrollablePanel, ma il suggerimento su quella pagina per modificare dinamicamente il valore restituito per Scrollable # getScrollableTracksViewportWidth funziona perfettamente. –

Problemi correlati