我必须同步表的水平滚动。列将是相同的,唯一可以更改的属性是列的大小。现在,以下代码显示了3个具有同步滚动的表。但是,当我更改任何表中任何一列的大小然后尝试滚动时,我收到堆栈溢出错误,并且gui失真。

我试图通过将其余表的视口位置设置为最先出现在左侧的列来实现此目的。
如果列的大小不同,则从该列的滚动百分比中,我正在重构其他表的位置。

import java.awt.Color;
import java.awt.Point;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

public class ScrollableJTable implements AdjustmentListener{
  JFrame frame = null;
  JPanel panel =  null;
  JTable table = null;
  JTableHeader header = null;
  JScrollPane pane = null;
  JTable table1 = null;
  JTableHeader header1 = null;
  JScrollPane pane1 = null;
  JTable table2 = null;
  JTableHeader header2 = null;
  JScrollPane pane2 = null;

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

    public ScrollableJTable() {
        frame = new JFrame("Creating a Scrollable JTable!");
        panel = new JPanel();
        String data[][] = {
            {"001", "vinod", "Bihar", "India", "Biology", "65", "First","001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"002", "Raju", "ABC", "Kanada", "Geography", "58", "second","001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"003", "Aman", "Delhi", "India", "computer", "98", "Dictontion","001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion","001", "vinod", "Bihar", "India", "Biology", "65", "First"}
        };
        String col[] = {"Roll", "Name", "State", "country", "Math", "Marks", "Grade","Roll", "Name", "State", "country", "Math", "Marks", "Grade"};
        table = new JTable(data, col);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header = table.getTableHeader();
        header.setBackground(Color.yellow);
        pane = new JScrollPane(table);
        pane.getHorizontalScrollBar().addAdjustmentListener(this);
        pane.setSize(100, 100);

        table1 = new JTable(data, col);
        table1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header1 = table1.getTableHeader();
        header1.setBackground(Color.yellow);
        pane1 = new JScrollPane(table1);
        pane1.getHorizontalScrollBar().addAdjustmentListener(this);
        pane1.setSize(100, 100);

        table2 = new JTable(data, col);
        table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header2 = table2.getTableHeader();
        header2.setBackground(Color.yellow);
        pane2 = new JScrollPane(table2);
        pane2.getHorizontalScrollBar().addAdjustmentListener(this);
        pane2.setSize(100, 100);

        panel.setSize(500, 500);
        panel.add(pane);
        panel.add(pane1);
        panel.add(pane2);
        frame.add(panel);
        frame.pack();
        frame.setSize(1000, 1000);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public void adjustmentValueChanged(AdjustmentEvent e) {

      JScrollPane scrollPane = null, scroll = null;
      JScrollBar bar = null;
      int position[] = null;


      bar = (JScrollBar) e.getAdjustable();
      scroll = (JScrollPane) bar.getParent();
      position = this.getFirstVisibleColumnIndex(scroll);
      for (int j = 0; j < panel.getComponentCount(); j++) {
        scrollPane = (panel.getComponent(j) instanceof JScrollPane) ? (JScrollPane) panel.getComponent(j) : null;
        if (scrollPane != null && scrollPane != scroll) this.setFirstColumnVisiblePosition(position, scrollPane);
      }

    }

    private int[] getFirstVisibleColumnIndex(JScrollPane scroll) {
      JTable table = null;
      TableColumnModel model = null;
      Object obj = null;
      int retval[] = null, index = -1, position = -1, relpos = -1;

      if (scroll == null) return null;
      obj = scroll.getViewport().getView();
      table = (obj instanceof JTable ? (JTable)obj : null);
      if (table == null) return null;
      model = table.getColumnModel();
      if (model == null) return null;

      position = scroll.getViewport().getViewPosition().x;
      for (int column = 0; index == -1 && column < model.getColumnCount(); column++) {
        position = position - model.getColumn(column).getWidth();
        if (position < 0) {
          index  = column;
          relpos = ((position + model.getColumn(column).getWidth()) * 100) / model.getColumn(column).getWidth();
        }
      }

      retval = new int[2];
      retval[0] = index;
      retval[1] = relpos;
      return retval;
    }


    private boolean setFirstColumnVisiblePosition(int position[], JScrollPane scroll) {
      JTable table = null;
      TableColumnModel model = null;
      Object obj = null;
      int pos = 0, width = 0;

      if (scroll == null || position == null) return false;
      obj = scroll.getViewport().getView();
      table = (obj instanceof JTable ? (JTable)obj : null);
      if (table == null) return false;
      model = table.getColumnModel();
      if (model == null) return false;
      if (position[0] == -1 || position [1] == -1) return false;

      for (int column = 0; column < position[0]; column++) {
        pos = pos + model.getColumn(column).getWidth();
      }
      width = model.getColumn(position[0]).getWidth();

      pos   = pos + ((position[1] * width) / 100);

      scroll.getViewport().setViewPosition(new Point(pos, scroll.getViewport().getViewPosition().y));
      return true;
    }
}

最佳答案

有一些重要问题,例如AdjustmentListener

仅对最后一个JScrollBar进行硬编码(不能注释某些内容,可以更好地知道所有JScrollBars的值并重新计算另一个JScrollBars的具体值)

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;

public class ScrollableJTable {

    private JFrame frame = null;
    private JPanel panel = null;
    private JTable table = null;
    private JTableHeader header = null;
    private JScrollPane pane = null;
    private JTable table1 = null;
    private JTableHeader header1 = null;
    private JScrollPane pane1 = null;
    private JTable table2 = null;
    private JTableHeader header2 = null;
    private JScrollPane pane2 = null;

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

    public ScrollableJTable() {
        frame = new JFrame("Creating a Scrollable JTable!");
        panel = new JPanel();
        String data[][] = {
            {"001", "vinod", "Bihar", "India", "Biology", "65", "First", "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"002", "Raju", "ABC", "Kanada", "Geography", "58", "second", "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"003", "Aman", "Delhi", "India", "computer", "98", "Dictontion", "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion", "001", "vinod", "Bihar", "India", "Biology", "65", "First"}
        };
        String col[] = {"Roll", "Name", "State", "country", "Math", "Marks", "Grade", "Roll", "Name", "State", "country", "Math", "Marks", "Grade"};
        table = new JTable(data, col);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header = table.getTableHeader();
        header.setBackground(Color.yellow);
        pane = new JScrollPane(table);
        pane.setPreferredSize(new Dimension(400, 200));
        table1 = new JTable(data, col);
        table1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header1 = table1.getTableHeader();
        header1.setBackground(Color.yellow);
        pane1 = new JScrollPane(table1);
        pane1.setPreferredSize(new Dimension(400, 200));
        table2 = new JTable(data, col);
        table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        header2 = table2.getTableHeader();
        header2.setBackground(Color.yellow);
        pane2 = new JScrollPane(table2);
        pane2.setPreferredSize(new Dimension(200, 200));
        panel.setSize(500, 500);
        panel.add(pane);
        panel.add(pane1);
        panel.add(pane2);
        frame.add(panel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        final JScrollBar bar = pane.getHorizontalScrollBar();
        final JScrollBar bar1 = pane1.getHorizontalScrollBar();
        final JScrollBar bar2 = pane2.getHorizontalScrollBar();
        bar2.addAdjustmentListener(new AdjustmentListener() {

            @Override
            public void adjustmentValueChanged(AdjustmentEvent e) {
                bar.setValue(e.getValue());
                bar1.setValue(e.getValue());
            }
        });
    }
}



不要使用setSize,大多数LayoutManagers接受PreferredSize(在我的代码示例中为硬编码)
FlowLayout(对于LayoutManager为内置JPanel)仅接受PreferredSize
使用JFrame#pack()胜于JFrame#setSize(int, int)
看一下InitialThread
(事件每个人都可以告诉您)AdjustmentListener的输出是在EDT上完成的,如果您想在屏幕上以不同大小计算不同invokeLater()的值,则将输出包装到JScrollBars,应该延迟输出然后更好,而不在屏幕上跳JScrollPane内容


编辑

不管怎样,我尝试过的一切都没有例外,只有在ColumnModel不等于RowModel的情况下,剩下的只是计算每个ScrollBars Models的比率

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;

public class ScrollableJTable {

    private JFrame frame = null;
    private JPanel panel = null;
    private JTable table = null;
    private JTableHeader header = null;
    private JScrollPane pane = null;
    private JTable table1 = null;
    private JTableHeader header1 = null;
    private JScrollPane pane1 = null;
    private JTable table2 = null;
    private JTableHeader header2 = null;
    private JScrollPane pane2 = null;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ScrollableJTable scrollableJTable = new ScrollableJTable();
            }
        });
    }

    public ScrollableJTable() {
        frame = new JFrame("Creating a Scrollable JTable!");
        panel = new JPanel();
        String data[][] = {
            {"001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"}
        };
        String data1[][] = {
            {"001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"}
        };
        String data2[][] = {
            {"001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "002", "Raju", "ABC", "Kanada", "Geography", "58", "second",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "003", "Aman", "Delhi", "India", "computer", "98", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"},
            {"004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First",
                "004", "Ranjan", "Bangloor", "India", "chemestry", "90", "Dictontion",
                "001", "vinod", "Bihar", "India", "Biology", "65", "First"}
        };
        String col[] = {"Roll", "Name", "State", "country", "Math", "Marks",
            "Grade", "Roll", "Name", "State", "country", "Math", "Marks", "Grade"};
        String col1[] = {"Roll", "Name", "State", "country", "Math", "Marks",
            "Grade", "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade"};
        String col2[] = {"Roll", "Name", "State", "country", "Math", "Marks",
            "Grade", "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade",
            "Roll", "Name", "State", "country", "Math", "Marks", "Grade"};
        table = new JTable(data, col);
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        header = table.getTableHeader();
        header.setBackground(Color.yellow);
        pane = new JScrollPane(table);
        pane.setPreferredSize(new Dimension(400, 200));
        table1 = new JTable(data1, col1);
        table1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table1.setPreferredScrollableViewportSize(table1.getPreferredSize());
        header1 = table1.getTableHeader();
        header1.setBackground(Color.yellow);
        pane1 = new JScrollPane(table1);
        pane1.setPreferredSize(new Dimension(400, 200));
        table2 = new JTable(data2, col2);
        table2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table2.setPreferredScrollableViewportSize(table2.getPreferredSize());
        header2 = table2.getTableHeader();
        header2.setBackground(Color.yellow);
        pane2 = new JScrollPane(table2);
        pane2.setPreferredSize(new Dimension(200, 200));
        panel.setSize(500, 500);
        panel.add(pane);
        panel.add(pane1);
        panel.add(pane2);
        frame.add(panel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        final JScrollBar bar = pane.getHorizontalScrollBar();
        final JScrollBar bar1 = pane1.getHorizontalScrollBar();
        final JScrollBar bar2 = pane2.getHorizontalScrollBar();
        bar2.addAdjustmentListener(new AdjustmentListener() {

            @Override
            public void adjustmentValueChanged(final AdjustmentEvent e) {
                if (e.getValueIsAdjusting()) {
                    final int i = bar.getMaximum();
                    if (e.getValue() > i) {
                        EventQueue.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                bar.setValue(i);
                            }
                        });
                    } else {
                        EventQueue.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                bar.setValue(e.getValue());
                            }
                        });
                    }
                    final int i1 = bar1.getMaximum();
                    if (e.getValue() > i1) {
                        EventQueue.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                bar1.setValue(i1);
                            }
                        });
                    } else {
                        EventQueue.invokeLater(new Runnable() {

                            @Override
                            public void run() {
                                bar1.setValue(e.getValue());
                            }
                        });
                    }
                }
            }
        });
    }
}

10-05 18:27