6

コンテンツ ペインが JXList である JScrollPane があります。リストでマウス ホイールを使用すると、リストが一度に 3 つの項目を移動します。これは、行の高さに関係なく、テーブルでも機能します。これを変更して、プラットフォームに関係なく、リストとテーブルの両方でスクロール距離が正確に 1 項目になるようにするにはどうすればよいですか? テーブル内の一部の行の高さが異なるため、ブロックの増分を設定してもうまくいきません。

4

2 に答える 2

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

本当の魔法は customAdjustmentListenerで行われ、現在の「スクロール位置」を 1 ブロックずつ増やします。例に示すように、これは上下に、そして異なる行サイズで機能します。


コメントで@kleopatraが述べたように、 a を使用してマウスホイールの動作のみを再定義することもできますMouseWheelListener

こちらの公式チュートリアルを参照してください。

于 2012-07-09T16:03:22.890 に答える