2012-07-09 97 views
5

我有一個JScrollPane,其內容窗格是一個JXList。當我在列表中使用鼠標滾輪時,列表一次只能執行三(3)個項目。無論行高如何,這也適用於表格。我怎樣才能改變這個 - 無論平臺 - 對於列表還是表格,滾動距離都是1個項目?設置塊增量不會剪切它,因爲表中的某些行具有不同的高度。如何讓JScrollPane滾動每行一個鼠標滾輪一行?

+0

@trashgod沒有找過一段時間 - 輪子真的好像映射到unitIncrement,並確實處理個別行高,所以我的懷疑是錯誤的。調整可滾動的實現可能會有所幫助,畢竟:-) – kleopatra 2012-07-09 16:15:59

+2

請參閱camickr的[鼠標滾輪控制器](http://tips4java.wordpress.com/2010/01/10/mouse-wheel-controller/) – aterai 2012-07-10 06:33:24

+0

@aterai hach​​ ..忘了那一個:-)絕對要走的路,考慮讓你的評論一個答案,以獲得一些真正的投票。 – kleopatra 2012-07-10 08:04:18

回答

7

純粹是出於興趣(和一點點無聊)的我創建了一個工作示例:

/** 
* Scrolls exactly one Item a time. Works for JTable and JList. 
* 
* @author Lukas Knuth 
* @version 1.0 
*/ 
public class Main { 

    private JTable table; 
    private JList list; 
    private JFrame frame; 

    private final String[] data; 

    /** 
    * This is where the magic with the "just one item per scroll" happens! 
    */ 
    private final AdjustmentListener singleItemScroll = new AdjustmentListener() { 
     @Override 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      // The user scrolled the List (using the bar, mouse wheel or something else): 
      if (e.getAdjustmentType() == AdjustmentEvent.TRACK){ 
       // Jump to the next "block" (which is a row". 
       e.getAdjustable().setBlockIncrement(1); 
      } 
     } 
    }; 

    public Main(){ 
     // Place some random data: 
     Random rnd = new Random(); 
     data = new String[120]; 
     for (int i = 0; i < data.length; i++) 
      data[i] = "Set "+i+" for: "+rnd.nextInt(); 
     for (int i = 0; i < data.length; i+=10) 
      data[i] = "<html>"+data[i]+"<br>Spacer!</html>"; 
     // Create the GUI: 
     setupGui(); 
     // Show: 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void setupGui(){ 
     frame = new JFrame("Single Scroll in Swing"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 
     frame.add(split); 

     // Add Data to the table: 
     table = new JTable(new AbstractTableModel() { 
      @Override 
      public int getRowCount() { 
       return data.length; 
      } 

      @Override 
      public int getColumnCount() { 
       return 1; 
      } 

      @Override 
      public Object getValueAt(int rowIndex, int columnIndex) { 
       return data[rowIndex]; 
      } 
     }); 
     for (int i = 0; i < data.length; i+=10) 
      table.setRowHeight(i, 30); 
     JScrollPane scroll = new JScrollPane(table); 
     // Add out custom AdjustmentListener to jump only one row per scroll: 
     scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); 
     split.add(scroll); 

     list = new JList<String>(data); 
     scroll = new JScrollPane(list); 
     // Add out custom AdjustmentListener to jump only one row per scroll: 
     scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); 
     split.add(scroll); 
    } 

    public static void main(String[] agrs){ 
     new Main(); 
    } 
} 

真正神奇的是在自定義AdjustmentListener,我們去哪裏,並增加完成當前的「滾動位置」由每次一個塊。如上例所示,這可以上下運行,並具有不同的行大小。


由於@kleopatra在評論中提到的,你也可以使用一個MouseWheelListener只能重新定義鼠標滾輪的行爲。

查看官方教程here

+0

這真是太棒了。太感謝了!我的意思是,當然,在某處可以/可以是.setScrollIncrement(int i),但這種方式也可以。簡單的說一下:這段代碼使得滾動條的頁面特徵(點擊句柄外部的欄)滾動嬰兒步驟,考慮到代碼將塊增量設置爲1「全局」,這並不是很奇怪。有沒有辦法改變鼠標滾輪的步長?另外,你能推薦一本關於Swing的書嗎? – xmjx 2012-07-09 21:30:20

+0

啊,得多評論一下。我很好奇爲什麼每次調用AdjustmentListener時都必須調用setBlockIncrement(1),所以我在創建滾動窗格時關閉了偵聽器並調用了一次setBlockIncrement(1)。看哪!這也適用於相同的不需要的副作用。我不記得這是什麼影響我的辦公室機器,所以我明天將在工作中進行測試。有時候我不喜歡Swing。 ;-) – xmjx 2012-07-09 21:42:21

+0

@xmjx for swing,只需閱讀sun/oracle提供的教程。我沒有爲此閱讀專門的書。 Swing非常強大,但它也不是最小的GUI框架。 – 2012-07-09 22:09:01