对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java [英] recursive calls to AdjustmentListener - StackOverFlow Error Swing Java

查看:112
本文介绍了对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to synchronize the horizontal scrolling of tables. The columns would be the same only property that can be changed for the columns is their size. Now the following code shows 3 tables with synchronised scrolling. But as i change size of any one column in any of the table and then try to scroll, i get an Stack Overflow error and the gui is distorted.

我试图通过将其余表的视口位置设置到左侧第一列的列来实现它。
如果列的大小不同,那么从该列滚动的百分比开始,我正在重建其他表的位置。

I am trying to achieve it by setting the viewport position of rest of the tables to the column which comes first on the left hand side. If the size of the columns are different then then from the percentage scrolled for that column i am reconstructing the position of other table.

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的具体值)

hardcoded for last JScrollBar only (cant comment something works, better coud be know the value for all JScrollBars and recalculate the concrete value for another 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());
            }
        });
    }
}




  1. don使用 setSize ,大部分 LayoutManagers 接受 PreferredSize (在我的代码示例中硬编码)

  1. don't use setSize, most of LayoutManagers accepting PreferredSize (hardcoded in my code example)

FlowLayout (built_in LayoutManager for JPanel )仅接受 PreferredSize

FlowLayout (built_in LayoutManager for JPanel) accepting only PreferredSize

使用 JFrame#pack() rether而不是 JFrame #setSize(int,int)

use JFrame#pack() rether than JFrame#setSize(int, int)

查看 InitialThread

(每个人都可以告诉你的事件)来自 AdjustmentListener 的输出完成EDT,如果你要计算不同大小的不同 JScrollBars 的值,请将输出换行到 invokeLater()在屏幕上,输出应该延迟然后更好,而不会在屏幕上跳过 JScrollPane s竞赛

(event everybody can tell you that) output from AdjustmentListener is done on EDT, wrap output to the invokeLater() in the case that you hare to calculate value for different JScrollBars with different size on the screen, output should be delayed and then nicer, without jumping of JScrollPanes contens on the screen

编辑

无论如何,我尝试的任何事情都不例外,只有在这种情况下ColumnModel不等于RowModel,rest只计算每个ScrollBars模型的比率

whatever, anything I tried no exception, only in the case that ColumnModel doesn't equals RowModel, rest is only to calculate the ratio for every 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());
                            }
                        });
                    }
                }
            }
        });
    }
}

这篇关于对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆