2011-02-09 94 views
12

可調整大小的JScrollPane的內容具有最小寬度。如果JScrollPane小於此寬度,則應顯示水平滾動條。如果它大於此寬度,則視口內容應該展開以填充整個視口。JScrollpane調整可變大小內容的大小

似乎是一個簡單的概念,我已經得到的東西的工作,但感覺像一個黑客:

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

調整大小的對話框觸發的ComponentListener,其中明確規定視景的首選大小,觸發組件驗證。但是,調整大小會導致抖動滾動條。有沒有更乾淨的方法來做到這一點?

編輯:感謝camickr爲ScrollablePanel鏈接,我修改了我的JPanel類來實現Scrollable,並動態地改變了getScrollableTracksViewportWidth()的返回值。

當視口很大時,我返回truegetScrollableTracksViewportWidth(),告訴JScrollPane使用我的組件填充視圖。當視口很小時,我返回false,滾動條出現。

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

    } 
} 

回答

7

不確定,但您可能可以使用Scrollable Panel。您可以配置組件大小調整(嘗試使用STRETCH)。該代碼適用於組件的首選大小,而不是最小大小,因此它可能不是您想要的。

+1

完美!我沒有使用ScrollablePanel類,但是該頁面上的動態更改Scrollable#getScrollableTracksViewportWidth的返回值的建議正在完美工作。 – 2011-02-10 17:47:08