2012-07-09 101 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