0

我有两个JTables 在里面水平对齐JScrollBar。当我在第一个中选择一个单元格时,JTable我希望另一个上的相应单元格JTable对齐。

我正在做的是,每次JTable选择第一个单元格时,我使用JTable.getCellRect()获取每个单元格的 y 位置然后使用JTable.scrollRectToVisible(firstJTableCell). 然后第二个中的单元格JTable变得可见,但我想知道如何将其与第一个中的选定单元格对齐JTable。 当在第一个中选择一个单元格时
,我有办法知道在第二个中选择哪个单元格。我想知道的是如何以编程方式对齐两个 JTables 单元格。JTableJTable

4

1 回答 1

1

可能有更好的方法来实现相同的结果,但本质上,您可以使用 anAdjustmentListener和 aListSelectionListener来监视对JScrollPanes 和JTables 的更改并将这些结果同步回另一个表(基于原始事件的源)

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class SyncedTables {

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

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

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

    public class TestPane extends JPanel {

        private JTable left;
        private JTable right;

        public TestPane() {

            setLayout(new GridLayout(1, 2));
            left = new JTable(createTableModel("L"));
            right = new JTable(createTableModel("R"));

            left.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            right.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

            JScrollPane leftScrollPane = new JScrollPane(left);
            JScrollPane rightScrollPane = new JScrollPane(right);

            AdjustmentHandler ah = new AdjustmentHandler(leftScrollPane, rightScrollPane);

            leftScrollPane.getVerticalScrollBar().addAdjustmentListener(ah);
            leftScrollPane.getHorizontalScrollBar().addAdjustmentListener(ah);
            rightScrollPane.getVerticalScrollBar().addAdjustmentListener(ah);
            rightScrollPane.getHorizontalScrollBar().addAdjustmentListener(ah);

            SelectionHandler sh = new SelectionHandler(left, right);
            left.getSelectionModel().addListSelectionListener(sh);
            right.getSelectionModel().addListSelectionListener(sh);

            add(leftScrollPane);
            add(rightScrollPane);

        }

        protected TableModel createTableModel(String prefix) {
            DefaultTableModel model = new DefaultTableModel(0, 50);
            for (int row = 0; row < 100; row++) {
                Object[] rowData = new Object[50];
                for (int col = 0; col < 50; col++) {
                    rowData[col] = prefix + "-" + row + "x" + col;
                }
                model.addRow(rowData);
            }
            return model;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }
    }

    public class SelectionHandler implements ListSelectionListener {

        private JTable left;
        private JTable right;
        private boolean ignore;

        public SelectionHandler(JTable left, JTable right) {
            this.left = left;
            this.right = right;
        }

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (!ignore) {
                ignore = true;
                if (e.getSource() == left.getSelectionModel()) {
                    sync(left, right);
                } else if (e.getSource() == right.getSelectionModel()) {
                    sync(left, right);
                }
                ignore = false;
            }
        }

        protected void sync(JTable master, JTable slave) {
            slave.clearSelection();
            int[] selectedRows = master.getSelectedRows();
            for (int row : selectedRows) {
                slave.addRowSelectionInterval(row, row);
            }
            int[] selectedColumns = master.getSelectedColumns();
            for (int cols : selectedColumns) {
                slave.addColumnSelectionInterval(cols, cols);
            }
        }
    }

    public class AdjustmentHandler implements AdjustmentListener {

        private JScrollPane left;
        private JScrollPane right;
        private boolean ignore;

        public AdjustmentHandler(JScrollPane left, JScrollPane right) {
            this.left = left;
            this.right = right;
        }

        @Override
        public void adjustmentValueChanged(AdjustmentEvent e) {
            if (!ignore) {
                ignore = true;
                Container parent = ((Component) e.getSource()).getParent();
                if (parent == left) {
                    sync(left, right);
                } else if (parent == right) {
                    sync(right, left);
                }
                ignore = false;
            }
        }

        protected void sync(JScrollPane master, JScrollPane slave) {
            slave.getHorizontalScrollBar().setValue(master.getHorizontalScrollBar().getValue());
            slave.getVerticalScrollBar().setValue(master.getVerticalScrollBar().getValue());
        }
    }
}
于 2013-04-04T07:00:00.900 回答