2011-02-09 29 views
12

Mi contenido de JScrollPane redimensionable tiene un ancho mínimo. Si el JScrollPane es más pequeño que este ancho, deberían aparecer barras de desplazamiento horizontales. Si es mayor que este ancho, el contenido de la ventana gráfica se debe expandir para llenar toda la ventana gráfica.JScrollpane cambio de tamaño con contenido de tamaño variable

parece un concepto simple, y tengo algo que funciona, pero se siente como un truco:

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(); 
     } 
    } 
} 

Cambiar el tamaño de la ventana activa la ComponentListener, que establece explícitamente el tamaño preferido de la vista de la ventana gráfica , activando la validación de componentes. Sin embargo, el cambio de tamaño provoca barras de desplazamiento nerviosas. ¿Hay una manera más limpia de hacer esto?

EDIT: gracias a camickr para el enlace ScrollablePanel, he modificado mi clase JPanel para implementar desplazable, y dinámicamente cambiar el valor de retorno para getScrollableTracksViewportWidth().

Cuando la ventana gráfica es grande, devuelvo true para getScrollableTracksViewportWidth(), indicándole a JScrollPane que complete la vista con mi componente. Cuando la ventana gráfica es pequeña, devuelvo false, por lo que aparecen las barras de desplazamiento.

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; 
     } 

    } 
} 

Respuesta

7

No estoy seguro, pero es posible que pueda utilizar el Scrollable Panel. Puede configurar el redimensionamiento del componente (intente usar STRETCH). El código funciona en el tamaño preferido del componente, no en el tamaño mínimo, por lo que puede no ser exactamente lo que desea.

+1

¡Perfecto! No estoy utilizando la clase ScrollablePanel, pero la sugerencia en esa página para cambiar dinámicamente el valor de retorno de Scrollable # getScrollableTracksViewportWidth funciona a la perfección. –

Cuestiones relacionadas