对AdjustmentListener的递归调用 - StackOverFlow Error Swing Java [英] recursive calls to 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());
}
});
}
}
-
don使用
setSize
,大部分LayoutManagers
接受PreferredSize
(在我的代码示例中硬编码)
don't use
setSize
, most ofLayoutManagers
acceptingPreferredSize
(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)
(每个人都可以告诉你的事件)来自 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 JScrollPane
s 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屋!