rekurencyjne wywołania do AdjustmentListener - StackOverFlow Błąd Swing Java

Muszę zsynchronizować przewijanie w poziomie tabel. Kolumny byłyby tą samą właściwością, którą można zmienić, aby kolumny były ich rozmiarem. Teraz poniższy kod pokazuje 3 tabele z zsynchronizowanym przewijaniem. Ale gdy zmieniam rozmiar dowolnej kolumny w dowolnej tabeli, a następnie próbuję przewijać, otrzymuję błąd przepełnienia stosu i gui jest zniekształcony.

Próbuję to osiągnąć, ustawiając pozycję rzutni reszty tabel na kolumnę, która jest pierwsza po lewej stronie. Jeśli rozmiar kolumn jest inny, to od procentu przewiniętego dla tej kolumny odtwarzam pozycję innej tabeli.

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

questionAnswers(1)

yourAnswerToTheQuestion