Java 同步两个JTable的视图
我有两个Java 同步两个JTable的视图,java,swing,jtable,jtableheader,jide,Java,Swing,Jtable,Jtableheader,Jide,我有两个JTables,一个在主视口,一个在页脚视口,使用JideScrollPane。 问题是,当自定义主JTable视图时,页脚JTable仍然是 同样,有什么方法可以同步他们的视图吗 谢谢 您可以应用:第一个JTable观察第二个JTable,反之亦然。然后将列表器添加到两个表中,以便在其中一个表被“定制”时,通知另一个表。基本上,“被通知”包含一个导致JTable更新的方法调用。 为此,您有两个选择: 使用“register”方法和 “通知”方法。在创建JTable时,将其注册到 观察者
JTables
,一个在主视口,一个在页脚视口,使用JideScrollPane
。
问题是,当自定义主JTable
视图时,页脚JTable
仍然是
同样,有什么方法可以同步他们的视图吗
谢谢
您可以应用:第一个JTable观察第二个JTable,反之亦然。然后将列表器添加到两个表中,以便在其中一个表被“定制”时,通知另一个表。基本上,“被通知”包含一个导致JTable更新的方法调用。
为此,您有两个选择:
- 为每个表的列模型创建自定义
TableColumnModelListener
- 调整大小后,同步列宽。发生这种情况时,您必须暂时禁用另一个侦听器
- 要移动列,请在
[作为练习离开]columnMoved(…)
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class JTableResizeColumnsDemo implements Runnable
{
JTable table1, table2;
TableColumnModelListener columnListener1, columnListener2;
Map<JTable, TableColumnModelListener> map;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new JTableResizeColumnsDemo());
}
public void run()
{
Vector<String> names = new Vector<String>();
names.add("One");
names.add("Two");
names.add("Three");
table1 = new JTable(null, names);
table2 = new JTable(null, names);
columnListener1 = new ColumnChangeListener(table1, table2);
columnListener2 = new ColumnChangeListener(table2, table1);
table1.getColumnModel().addColumnModelListener(columnListener1);
table2.getColumnModel().addColumnModelListener(columnListener2);
map = new HashMap<JTable, TableColumnModelListener>();
map.put(table1, columnListener1);
map.put(table2, columnListener2);
JPanel p = new JPanel(new GridLayout(2,1));
p.add(new JScrollPane(table1));
p.add(new JScrollPane(table2));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p);
frame.setSize(300, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class ColumnChangeListener implements TableColumnModelListener
{
JTable sourceTable;
JTable targetTable;
public ColumnChangeListener(JTable source, JTable target)
{
this.sourceTable = source;
this.targetTable = target;
}
public void columnAdded(TableColumnModelEvent e) {}
public void columnSelectionChanged(ListSelectionEvent e) {}
public void columnRemoved(TableColumnModelEvent e) {}
public void columnMoved(TableColumnModelEvent e) {}
public void columnMarginChanged(ChangeEvent e)
{
TableColumnModel sourceModel = sourceTable.getColumnModel();
TableColumnModel targetModel = targetTable.getColumnModel();
TableColumnModelListener listener = map.get(targetTable);
targetModel.removeColumnModelListener(listener);
for (int i = 0; i < sourceModel.getColumnCount(); i++)
{
targetModel.getColumn(i).setPreferredWidth(sourceModel.getColumn(i).getWidth());
}
targetModel.addColumnModelListener(listener);
}
}
}
import java.awt.*;
导入java.util.*;
导入javax.swing.*;
导入javax.swing.event.*;
导入javax.swing.table.*;
公共类JTableResizeColumnsDemo实现Runnable
{
j表1、表2;
TableColumnModelListener columnListener1、columnListener2;
地图;
公共静态void main(字符串[]args)
{
invokeLater(新的JTableResizeColumnsDemo());
}
公开募捐
{
向量名称=新向量();
名称。添加(“一”);
名称。添加(“两个”);
名称。添加(“三”);
表1=新的JTable(空,名称);
表2=新的JTable(空,名称);
columnListener1=新ColumnChangeListener(表1、表2);
columnListener2=新ColumnChangeListener(表2,表1);
表1.getColumnModel().addColumnModelListener(columnListener1);
表2.getColumnModel().addColumnModelListener(columnListener2);
map=新的HashMap();
map.put(表1,columnListener1);
map.put(表2,columnListener2);
JPanel p=新JPanel(新网格布局(2,1));
p、 添加(新的JScrollPane(表1));
p、 添加(新的JScrollPane(表2));
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(p);
框架。设置尺寸(300200);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
类ColumnChangeListener实现TableColumnModelListener
{
JTable源表;
JTable-targetable;
公共ColumnChangeListener(JTable源、JTable目标)
{
this.sourceTable=source;
this.targetTable=目标;
}
添加了公共空列(TableColumnModelEvent e){}
public void columnSelectionChanged(ListSelectionEvent e){}
已删除公共空列(TableColumnModelEvent e){}
public void columnMoved(TableColumnModelEvent e){}
公共无效列边际变更(变更事件e)
{
TableColumnModel sourceModel=sourceTable.getColumnModel();
TableColumnModel targetModel=targetTable.getColumnModel();
TableColumnModelListener=map.get(targetTable);
removeColumnModelListener(listener);
对于(int i=0;i
通常这是通过为不同的ui组件使用相同的模型来实现的。遗憾的是,JTable
中包含的内容在共享TableColumnModel
时会导致问题
但您可以使用此JTable
class ShareableColumnModelTable extends JTable {
/**
* Fixes http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4816146 and
* more...
*
*/
@Override
public void columnMarginChanged(ChangeEvent e) {
if (isEditing()) {
removeEditor();
}
TableColumn resizingColumn = null;
if (tableHeader != null) {
resizingColumn = tableHeader.getResizingColumn();
}
if (resizingColumn != null) {
if (autoResizeMode == AUTO_RESIZE_OFF) {
resizingColumn.setPreferredWidth(resizingColumn.getWidth());
} else { // this else block is missing in jdk1.4 as compared to
// 1.3
TableColumnModel columnModel = getColumnModel();
/**
* Temporarily disconnects this column listener to prevent
* stackoverflows if the column model is shared between
* multiple JTables.
*/
columnModel.removeColumnModelListener(this);
try {
doLayout();
} finally {
columnModel.addColumnModelListener(this);
}
repaint();
return;
}
}
resizeAndRepaint();
}
}
使用上面显示的ShareableColumnModelTable
,您可以在多个表中更好地共享一列模型
public static void main(String[] args) {
JFrame frame = new JFrame("Column Sync");
Container contentPane = frame.getContentPane();
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setResizeWeight(0.5d);
contentPane.add(splitPane);
JTable table1 = new ShareableColumnModelTable();
JTable table2 = new ShareableColumnModelTable();
TableColumnModel tableColumnModel = createTableColumnModel();
table1.setModel(createTableModel1());
table2.setModel(createTableModel2());
table1.setColumnModel(tableColumnModel);
table2.setColumnModel(tableColumnModel);
splitPane.setLeftComponent(new JScrollPane(table1));
splitPane.setRightComponent(new JScrollPane(table2));
showFrame(frame);
}
private static TableColumnModel createTableColumnModel() {
TableColumnModel tableColumnModel = new DefaultTableColumnModel();
TableColumn column1 = new TableColumn(0);
column1.setHeaderValue("1. column");
tableColumnModel.addColumn(column1);
TableColumn column2 = new TableColumn(1);
column2.setHeaderValue("2. column");
tableColumnModel.addColumn(column2);
return tableColumnModel;
}
private static TableModel createTableModel1() {
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.setColumnCount(2);
tableModel.addRow(new Object[] { "a", "b" });
return tableModel;
}
private static TableModel createTableModel2() {
DefaultTableModel tableModel = new DefaultTableModel();
tableModel.setColumnCount(2);
tableModel.addRow(new Object[] { "c", "d" });
return tableModel;
}
private static void showFrame(JFrame frame) {
frame.setSize(240, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
}
我确实考虑过这一点,遗憾的是,我不知道应该如何或确切地观察什么,因为JTable没有明显的视图面。另外,将它们设置为具有相同的模型只会定义它们的初始布局(数据+初始视图),而不是当前视图。好的,它确实有效。只需运行这个自包含的演示,您就会看到。很明显,您必须做一些不同的事情,但我不能说什么,因为您没有显示任何代码。为了更快地获得更好的帮助,请发布一个演示问题的帖子。我不希望数据被共享,我需要视图。主要是列的顺序和宽度,在运行时由用户修改,不修改基础数据。您想要两个具有相同结构(列标题等)但数据不同的表吗?如果是,那么您希望同步的是什么?滚动?列标题大小调整?还有什么?列标题的大小和顺序。主要是外表。页脚中的表应该是一个筛选行。@user3719495请参阅文章中的“我的编辑”。