2011-02-09 64 views
12

Nội dung JScrollPane có thể thay đổi kích cỡ của tôi có chiều rộng tối thiểu. Nếu JScrollPane nhỏ hơn chiều rộng này, các thanh cuộn ngang sẽ xuất hiện. Nếu nó lớn hơn chiều rộng này, nội dung khung nhìn sẽ mở rộng để lấp đầy toàn bộ chế độ xem.Thay đổi kích thước JScrollpane với nội dung có kích thước thay đổi

Có vẻ như một khái niệm đơn giản, và tôi đã có cái gì đó đang làm việc, nhưng nó cảm thấy như một 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(); 
     } 
    } 
} 

Thay đổi kích thước hộp thoại kích hoạt ComponentListener, đặt một cách rõ ràng kích thước ưa thích của cái nhìn viewport , kích hoạt xác thực thành phần. Tuy nhiên, thay đổi kích thước gây ra thanh cuộn jittery. Có cách nào sạch hơn để làm việc này không?

EDIT: nhờ camickr cho liên kết ScrollablePanel, tôi đã sửa đổi lớp JPanel của mình để triển khai Có thể cuộn và tự động thay đổi giá trị trả về cho getScrollableTracksViewportWidth().

Khi chế độ xem lớn, tôi trả lại true cho getScrollableTracksViewportWidth(), yêu cầu JScrollPane điền vào chế độ xem với thành phần của tôi. Khi chế độ xem nhỏ, tôi trả lại false, do đó các thanh cuộn xuất hiện.

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

    } 
} 

Trả lời

7

Không chắc chắn, nhưng bạn có thể sử dụng Scrollable Panel. Bạn có thể cấu hình thay đổi kích thước thành phần (thử sử dụng STRETCH). Mã hoạt động trên kích thước ưa thích của thành phần không phải kích thước tối thiểu để nó có thể không chính xác những gì bạn muốn.

+1

Hoàn hảo! Tôi không sử dụng lớp ScrollablePanel, nhưng đề xuất trên trang đó để tự động thay đổi giá trị trả lại cho Scrollable # getScrollableTracksViewportWidth đang hoạt động hoàn hảo. –

Các vấn đề liên quan