java - 对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java

标签 java swing jtable jscrollpane jscrollbar

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

我试图通过将其余表格的视口(viewport)位置设置为左侧第一个列来实现它。 如果列的大小不同,那么根据该列的滚动百分比,我正在重建其他表的位置。

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仅限(无法评论某些内容是否有效,最好了解所有 JScrollBar 的值并重新计算另一个 JScrollBar 的具体值)

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());
            }
        });
    }
}
  1. 不要使用setSize ,大部分LayoutManagers接受PreferredSize (在我的代码示例中硬编码)

  2. FlowLayout (内置 LayoutManagerJPanel )仅接受 PreferredSize

  3. 使用JFrame#pack()而非 JFrame#setSize(int, int)

  4. 看看InitialThread

  5. (每个人都可以告诉你的事件)AdjustmentListener 的输出在 EDT 上完成,将输出包装到 invokeLater()如果您必须计算不同 JScrollBars 的值屏幕尺寸不同,输出应该延迟然后更好,而不跳JScrollPane屏幕上的内容

编辑

无论如何,我尝试过的任何方法都没有异常(exception),只有在ColumnModel不等于RowModel的情况下,剩下的只是计算每个ScrollBars模型的比率

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

关于java - 对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12707669/

相关文章:

java - 在没有 split 方法/数组的情况下,如何在 Java 中从字符串中提取整数并将它们加在一起?

java - 在 Spring-boot 中为特定的异步请求设置超时

java - 这两种冒泡排序实现之间的区别

java - 奇怪的 Swing 故障?

java - 如何从 Swing 的 JTextField 中获取整数值?

java - 在 JTable 中显示金钱,但保留按 double 排序的能力

java - JTable:没有行,高度尺寸错误

java - 如何在 Java 中将对象转换为 JTable

java - Date : Java 中的代码优化

java - GridBagLayout 扩展列