2012-07-09 17 views
5

私はコンテンツペインがJXListであるJScrollPaneを持っています。リスト上でマウスホイールを使用すると、リストは一度に3つのアイテムを処理します。これは、行の高さに関係なく、表に対しても機能します。どのようにしてこれを変更することができます - プラットフォームに関係なく、リストとテーブルの両方のスクロール距離はちょうど1アイテムですか?テーブル内のいくつかの行の高さが異なるため、ブロック増分を設定してもそれをカットしません。純粋な興味(と少し退屈)のうちJScrollPaneのスクロールをマウスホイールステップごとに1行にする方法は?

+0

@trashgodはしばらく探していませんでした。ホイールは実際にはunitIncrementにマップされているようですが、個々の行の高さを処理するので疑問に間違っていました。結局のところ、スクロール可能な実装を調整すると、助けになるかもしれません。 – kleopatra

+2

camickrの[マウスホイールコントローラ](http://tips4java.wordpress.com/2010/01/10/mouse-wheel-controller/) – aterai

+0

@aterai hach​​ ..そのことを忘れてしまった:-)間違いなく、あなたのコメントを答えにして、実際の投票を取ることを検討してください。 – kleopatra

答えて

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、で行われている現在の「スクロール位置」によって、 1つの時間あたり1つのブロック。この例では、これは上下および異なる行サイズで動作します。コメントで述べた


@kleopatra として、あなたはまた、唯一のマウスホイールの動作を再定義するMouseWheelListenerを使用することができます。

公式チュートリアルhereを参照してください。

+0

これはかなり素晴らしいです。感謝万円!私はどこかに.setScrollIncrement(int i)が存在する可能性がありますが、この方法でも動作します。このコードでは、スクロールバーのページ機能(ハンドルの外側にあるバーをクリックする)は、ブロックのインクリメントを「グローバルに」1に設定することを考慮すると、奇妙なことではありません。マウスホイールのステップサイズを変更する方法はありますか?また、スイングに関する本をお勧めしますか? – xmjx

+0

ああ、ちょっとコメントをください。なぜ、AdjustmentListenerが呼び出されるたびにsetBlockIncrement(1)を呼び出さなければならないのか不思議でした。そのため、スクロールペインの作成時にリスナーを無効にしてsetBlockIncrement(1)を呼び出しました。見よ!これは、同じ望ましくない副作用でも機能します。明日の仕事でこれをテストします。時々私はSwingが好きではない。 ;-) – xmjx

+0

@xmjxをスイングするには、sun/oracleが提供するチュートリアルを読んでください。私はそのための専用の本を読まなかった。 Swingは非常に強力ですが、GUIフレームワークの中でも最小のものです。 –

関連する問題