1

これが私が使ってきたものの例の表です:

JScrollPane scrollPane = new JScrollPane();
contentPane.add(scrollPane);

table = new JTable();
DefaultTableModel tableModel = new DefaultTableModel(new Object[]{"Row 1","Row 2"},0);
table.setModel(tableModel);
scrollPane.setViewportView(table);

次の自動スクロール方法を両方とも同じ結果で使用しようとしました。

// Method 1
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());

// Method 2
table.scrollRectToVisible(table.getCellRect(table.getRowCount(), 0, true));

両方の例は、ユーザーが表示するために下にスクロールする必要がある最後の (一番下の) 行まで、テーブルの一番下近くに移動し、別の行が追加されたときにのみ再び発生します。


編集: 問題を再現するコード例

import java.awt.*;
import javax.swing.*;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;

public class ScrollTableEx extends JFrame {

    private static final long serialVersionUID = 1L;
    public int i = 100;
    public JScrollPane scrollPane;
    public JPanel contentPane;
    public JTable table;
    public JButton add;
    public DefaultTableModel model = new DefaultTableModel(new Object[] { "Int (+)", "Int (-)" }, 0);

    public static void main(String[] args) {
        ScrollTableEx frame = new ScrollTableEx();
        frame.setVisible(true);
    }

    public ScrollTableEx() {
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setSize(500,400);
        
        scrollPane = new JScrollPane();

        table = new JTable();
        table.setCellSelectionEnabled(true);
        table.setModel(model);
        scrollPane.setViewportView(table);

        for (int i = 0; i < 100; i++) {
            model.addRow(new Object[] { i, i * -1 });
            Rectangle goodRect = table.getCellRect(model.getRowCount() - 1, 0, true);
            table.scrollRectToVisible(goodRect);
        }

        JButton add = new JButton("Add");
        add.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                Rectangle goodRect = table.getCellRect(model.getRowCount() - 1, 0, true);
                table.scrollRectToVisible(goodRect);
                model.addRow(new Object[] { i, i * -1 });
                i++;
            }
        });
        
        add(add, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
    }
}
4

1 に答える 1

4

問題は、JTable両方TableModelとも0索引付けされていることです。つまり、最後の値は実際にはrowCount - 1です。

したがって、 を使用すると、行が実際には存在しないため、実際には高さだけで正しい位置table.getCellRect(table.getRowCount(), 0, true)の が返されます。Rectangle0

代わりに使用したいtable.getCellRect(table.getRowCount() - 1, 0, true)

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;

public class ScrollTable {

    public static void main(String[] args) {
        new ScrollTable();
    }

    public ScrollTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                final DefaultTableModel model = new DefaultTableModel(new Object[]{"Test"}, 0);
                for (int index = 0; index < 100; index++) {
                    model.addRow(new Object[]{index});
                }

                final JTable table = new JTable(model);

                JButton add = new JButton("Add");
                add.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        model.addRow(new Object[]{model.getRowCount()});
                        Rectangle badRect = table.getCellRect(model.getRowCount(), 0, true);
                        Rectangle goodRect = table.getCellRect(model.getRowCount() - 1, 0, true);

                        System.out.println("bad = " + badRect);
                        System.out.println("goodRect = " + goodRect);

                        table.scrollRectToVisible(goodRect);
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.add(add, BorderLayout.SOUTH);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

可能な限り使用を避けたいと思い.setBoundsます。異なるコンピューターとOSの間に存在するさまざまな違いは考慮されていません。開発中は完全に問題なく見えるかもしれませんが、別のシステムに移動すると、望ましくない結果が生じる可能性があります-IMHO

于 2013-08-21T00:27:54.327 に答える