我正在创建一个包含2个JTable的自定义组件,一个作为主数据网格,另一个作为始终可见的摘要栏,我已经提出了这个解决方案,但调整列的工作原理不应该如此,任何想法都有我错了吗?
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
public class FixedRow2Tables extends JFrame
{
private static final long serialVersionUID = 4676303089799270571L;
Object[][] data;
Object[] column;
JTable fixedTable, table;
public FixedRow2Tables()
{
super("Fixed Row Example");
Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" },
{ "", "b", "", "", "", "" }, { "", "", "c", "", "", "" },
{ "", "", "", "d", "", "" }, { "", "", "", "", "e", "" },
{ "", "", "", "", "", "f" } };
Object[][] summaryData = { { "fixed1", "", "", "", "", "" },
{ "fixed2", "", "", "", "", "" } };
column = new Object[] { "A", "B", "C", "D", "E", "F" };
table = new JTable(mainData, column);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fixedTable = new JTable(summaryData, column);
fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fixedTable.setTableHeader(null);
fixedTable.setColumnModel(table.getColumnModel());
JScrollPane scroll = new JScrollPane(table);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setPreferredSize(new Dimension(400, 100));
getContentPane().add(scroll, BorderLayout.CENTER);
getContentPane().add(fixedTable, BorderLayout.SOUTH);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
FixedRow2Tables frame = new FixedRow2Tables();
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
});
}
}
答案 0 :(得分:2)
fixedTable.setColumnModel(table.getColumnModel());
问题出在那条线上。如果您将其注释掉,则表格表现正常。如果这会破坏你的代码(因为我不知道你想要做什么)只需评论。
但是,正如您在评论中添加的那样,您希望同步这两个表。我找到了一个完全涵盖该问题的论坛帖子:
http://forums.sun.com/thread.jspa?threadID=713021
玩得开心!
P.S。:以防论坛帖子线程消失(只是复制了文本):
首先勾选表格。不得不分享ColumnModel否则它不起作用。这些面板都有一个JTable字段,set和get ColumnModel方法委托给JTable。
infoPanel.setColumnModel(overviewPanel.getColumnModel());
overviewPanel.getColumnModel().addColumnModelListener(infoPanel);
infoPanel.getColumnModel().addColumnModelListener(overviewPanel);
然后处理ChangeEvent:
public void columnMarginChanged(ChangeEvent event) {
final TableColumnModel eventModel = (DefaultTableColumnModel)event.getSource();
final TableColumnModel thisModel = getTable().getColumnModel();
final int columnCount = eventModel.getColumnCount();
for (int i = 0; i < columnCount; i++) {
thisModel.getColumn(i).setWidth(eventModel.getColumn(i).getWidth());
}
repaint();
}
答案 1 :(得分:1)
这段代码为我修好了。
请注意,不在表之间重用columnModel。请参阅代码中的注释。
package snippet;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.TableColumnModel;
public class FixedRow2Tables extends JFrame {
private static final long serialVersionUID = 4676303089799270571L;
Object[][] data;
Object[] column;
JTable footerTable, table;
public FixedRow2Tables() {
super("Fixed Row Example");
Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" },
{ "", "b", "", "", "", "" }, { "", "", "c", "", "", "" },
{ "", "", "", "d", "", "" }, { "", "", "", "", "e", "" },
{ "", "", "", "", "", "f" } };
Object[][] summaryData = { { "fixed1", "", "", "", "", "" },
{ "fixed2", "", "", "", "", "" } };
column = new Object[] { "A", "B", "C", "D", "E", "F" };
table = new JTable(mainData, column);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
footerTable = new JTable(summaryData, column);
footerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
footerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
footerTable.setTableHeader(null);
// footerTable.setColumnModel(table.getColumnModel());
table.getColumnModel().addColumnModelListener(
new TableColumnModelListener() {
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
}
@Override
public void columnMarginChanged(ChangeEvent e) {
final TableColumnModel tableColumnModel = table
.getColumnModel();
TableColumnModel footerColumnModel = footerTable
.getColumnModel();
for (int i = 0; i < tableColumnModel.getColumnCount(); i++) {
int w = tableColumnModel.getColumn(i).getWidth();
footerColumnModel.getColumn(i).setMinWidth(w);
footerColumnModel.getColumn(i).setMaxWidth(w);
// footerColumnModel.getColumn(i).setPreferredWidth(w);
}
footerTable.doLayout();
footerTable.repaint();
repaint();
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
});
JScrollPane scroll = new JScrollPane(table);
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scroll.setPreferredSize(new Dimension(400, 100));
getContentPane().add(scroll, BorderLayout.CENTER);
getContentPane().add(footerTable, BorderLayout.SOUTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
FixedRow2Tables frame = new FixedRow2Tables();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
});
}
}
答案 2 :(得分:1)
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
class Application extends JFrame
{
public Application()
{
this.setBounds(100,100,500,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String data[][] = {{"a1","b1","c1"},{"a2","b2","c2"},{"a3","b3","c3"}};
String columnNames[] = {"a","b","c"};
JTable jtable = new JTable(new DefaultTableModel(data,columnNames));
JScrollPane jscrollPane = new JScrollPane(jtable,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jscrollPane.setBorder(new CompoundBorder(new MatteBorder(0,0,1,0,Color.gray),new EmptyBorder(0,0,0,0)));
this.add(jscrollPane,BorderLayout.CENTER);
JTable jtable_footer = new JTable(new DefaultTableModel(3,columnNames.length),jtable.getColumnModel());
SyncListener syncListener = new SyncListener(jtable,jtable_footer);
this.add(jtable_footer,BorderLayout.SOUTH);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Application application = new Application();
application.setVisible(true);
}
});
}
}
class SyncListener implements TableColumnModelListener
{
JTable jtable_data;
JTable jtable_footer;
public SyncListener(JTable main, JTable footer)
{
jtable_data = main;
jtable_footer = footer;
DefaultTableColumnModel dtcm = (DefaultTableColumnModel)jtable_data.getColumnModel();
dtcm.removeColumnModelListener(dtcm.getColumnModelListeners()[1]);
dtcm.addColumnModelListener(this);
}
public void columnMarginChanged(ChangeEvent changeEvent)
{
for (int column = 0; column < jtable_data.getColumnCount(); column++)
{
jtable_footer.getColumnModel().getColumn(column).setWidth(jtable_data.getColumnModel().getColumn(column).getWidth());
}
jtable_footer.repaint();
}
public void columnAdded(TableColumnModelEvent e){}
public void columnMoved(TableColumnModelEvent e){}
public void columnRemoved(TableColumnModelEvent e){}
public void columnSelectionChanged(ListSelectionEvent e){}
}
答案 3 :(得分:1)
我解决这个问题的方法(代码在Kotlin中):
class TableHack(model: TableModel) : JXTable(model) {
override fun columnMarginChanged(e: ChangeEvent?) {
repaint();
return;
}
}
将此表用作“摘要”-table,并从主表中设置ColumnModel
。
问题的原因似乎是resizeAndRepaint()
,它是从表中的默认实现调用的。如果用简单的repaint()
替换它,它就像魅力一样。
答案 4 :(得分:0)
通过上面的例子,我添加了一些带有水平滚动条和列顺序的东西:
package test;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
import javax.swing.JFrame;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class FixedRow2Tables extends JFrame
{
class FixedFooterTable extends JTable {
private TableColumnModelListener tableColumnModelListener;
private JTable bindedTable;
FixedFooterTable(Object[][] data, String[] columnNames) {
super(data, columnNames);
setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setCellSelectionEnabled(true);
}
public void bindTableModels(final JTable table) {
this.bindedTable = table;
if (tableColumnModelListener == null)
tableColumnModelListener = new TableColumnModelListener() {
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
if (e.getFromIndex() < getColumnCount()) {
TableColumn c = getColumnModel().getColumn(e.getFromIndex());
getColumnModel().removeColumn(c);
}
}
@Override
public void columnMoved(TableColumnModelEvent e) {
if (e.getFromIndex() < getColumnCount() && e.getToIndex() < getColumnCount()) {
TableColumn c = getColumnModel().getColumn(e.getFromIndex());
getColumnModel().moveColumn(e.getFromIndex(), e.getToIndex());
}
}
@Override
public void columnMarginChanged(ChangeEvent e) {
bindColumnWidths(table.getColumnModel());
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
};
table.getColumnModel().addColumnModelListener(tableColumnModelListener);
}
private void bindColumnWidths(final TableColumnModel columnModel) {
TableColumnModel fixedColumnModel = getColumnModel();
Enumeration<TableColumn> enumerator = columnModel.getColumns();
while (enumerator.hasMoreElements()) {
TableColumn c = enumerator.nextElement();
if (c.getModelIndex() >= fixedColumnModel.getColumnCount())
break;
TableColumn destColumn = fixedColumnModel.getColumn(c.getModelIndex());
System.out.println("columnMarginChanged c" + c.getModelIndex() + " : " + c.getWidth() + " - " + destColumn.getWidth() + " : "
+ (destColumn.getWidth() - c.getWidth()));
destColumn.setPreferredWidth(c.getWidth());
System.out.println("columnMarginChanged c" + c.getModelIndex() + " : " + c.getWidth() + " - " + destColumn.getWidth());
}
revalidate();
}
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
public void bindViews(final JScrollPane scrollPane, final JScrollPane fixedScrollPane) {
final JScrollBar fixedHorScrollBar = fixedScrollPane.getHorizontalScrollBar();
final JScrollBar horScrollBar = scrollPane.getHorizontalScrollBar();
final JScrollBar verScrollBar = scrollPane.getVerticalScrollBar();
fixedScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
fixedScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
horScrollBar.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
fixedHorScrollBar.setValue(e.getValue());
}
});
verScrollBar.addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
Dimension d = fixedScrollPane.getSize();
Dimension d1 = scrollPane.getSize();
}
});
}
public JTable getBindedTable() {
return bindedTable;
}
}
private static final long serialVersionUID = 4676303089799270571L;
Object[][] data;
String[] columnNames;
FixedFooterTable fixedTable;
JTable table;
public FixedRow2Tables()
{
super("Fixed Row Example");
Object[][] mainData = new Object[][] { { "a", "", "", "", "", "" },
{ "", "b", "", "", "", "" }, { "", "", "c", "", "", "" },
{ "", "", "", "d", "", "" }, { "", "", "", "", "e", "" },
{ "", "", "", "", "", "f" },
{ "a", "b", "c", "d", "e", "f" },
{ "a", "b", "c", "d", "e", "f" },
{ "a", "b", "c", "d", "e", "f" },
{ "a", "b", "c", "d", "e", "f" },
{ "a", "b", "c", "d", "e", "f" } };
Object[][] summaryData = { { "fixed1", "", "", "", "", "" },
{ "fixed2", "b", "c", "d", "e", "f" } };
columnNames = new String[] { "Ala", "Bardzo", "Chciala", "Dostac", "Eskimoska", "Franciszki Genowefy Pigwy" };
table = new JTable(mainData, columnNames);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
fixedTable = new FixedFooterTable(summaryData, columnNames);
fixedTable.setTableHeader(null);
final JScrollPane scroll = new JScrollPane(table);
final JScrollPane fixedscroll = new JScrollPane(fixedTable);
Dimension preferredSize = fixedTable.getPreferredSize();
fixedscroll.setPreferredSize(preferredSize);
fixedTable.bindTableModels(table);
fixedTable.bindViews(scroll, fixedscroll);
getContentPane().add(scroll, BorderLayout.CENTER);
getContentPane().add(fixedscroll, BorderLayout.SOUTH);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
FixedRow2Tables frame = new FixedRow2Tables();
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
frame.pack();
frame.setVisible(true);
}
});
}
}