【发布时间】:2015-01-09 12:36:54
【问题描述】:
问题描述:
原来有两张表:
在左表的顶部有两个元素:JTextField 和 JComboBox,它们被放在一个单独的 JPanel 中。表格过滤需要这两个元素,即更改选定的组合框元素或在左侧的 JTextField 获取表格中输入内容被过滤掉。
我尝试实现 TableColumnModelListener 接口以便将 JTextField 和 JComboBox 元素连接到表格。结果不如我预期的那么好:在 JPanel 容器对象上调用的 revalidate() 方法破坏了整个摇摆元素的组合。该实验的结果如下图所示:
源代码:
TablesTest 类:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TablesTest {
private JFrame frame = new JFrame();
private javax.swing.JPanel commonTablesPanel;
private javax.swing.JPanel dataTable1Panel;
private javax.swing.JPanel dataTable2Panel;
private javax.swing.JTable datatable1Table;
private javax.swing.JTable datatable2Table;
private javax.swing.JComboBox filterComboBox;
private javax.swing.JPanel filterPanel;
private javax.swing.JTextField filterTextField;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JScrollPane jScrollPane4;
private TableResizeListener tableResizeListener1;
public TablesTest() {
java.awt.GridBagConstraints gridBagConstraints;
commonTablesPanel = new javax.swing.JPanel();
dataTable1Panel = new javax.swing.JPanel();
filterPanel = new javax.swing.JPanel();
filterTextField = new javax.swing.JTextField();
filterComboBox = new javax.swing.JComboBox();
jScrollPane3 = new javax.swing.JScrollPane();
datatable1Table = new javax.swing.JTable();
dataTable2Panel = new javax.swing.JPanel();
jScrollPane4 = new javax.swing.JScrollPane();
datatable2Table = new javax.swing.JTable();
frame.setLayout(new java.awt.GridBagLayout());
commonTablesPanel.setMinimumSize(new java.awt.Dimension(30, 30));
commonTablesPanel.setPreferredSize(new java.awt.Dimension(30, 30));
commonTablesPanel.setLayout(new java.awt.GridBagLayout());
dataTable1Panel.setLayout(new java.awt.GridBagLayout());
filterPanel.setLayout(new java.awt.GridBagLayout());
filterTextField.setPreferredSize(new java.awt.Dimension(30, 20));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
filterPanel.add(filterTextField, gridBagConstraints);
filterComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
filterComboBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
//TODO
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
filterPanel.add(filterComboBox, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
dataTable1Panel.add(filterPanel, gridBagConstraints);
jScrollPane3.setPreferredSize(new java.awt.Dimension(30, 30));
datatable1Table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null}
},
new String [] {
"Title 1", "Titile 2"
}
));
datatable1Table.setMinimumSize(new java.awt.Dimension(30, 30));
jScrollPane3.setViewportView(datatable1Table);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 0.1;
gridBagConstraints.weighty = 0.1;
dataTable1Panel.add(jScrollPane3, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 0.1;
gridBagConstraints.weighty = 0.1;
commonTablesPanel.add(dataTable1Panel, gridBagConstraints);
dataTable2Panel.setLayout(new java.awt.GridBagLayout());
jScrollPane4.setPreferredSize(new java.awt.Dimension(30, 30));
datatable2Table.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null},
{null, null}
},
new String [] {
"Titile 1", "Title 2"
}
) {
boolean[] canEdit = new boolean [] {
false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
datatable2Table.setMinimumSize(new java.awt.Dimension(30, 30));
jScrollPane4.setViewportView(datatable2Table);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 0.1;
gridBagConstraints.weighty = 0.1;
dataTable2Panel.add(jScrollPane4, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 0.1;
gridBagConstraints.weighty = 0.1;
commonTablesPanel.add(dataTable2Panel, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 0.1;
gridBagConstraints.weighty = 0.1;
gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 4);
frame.add(commonTablesPanel, gridBagConstraints);
tableResizeListener1 = new TableResizeListener(datatable1Table, filterPanel);
frame.setPreferredSize(new Dimension(400,150));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TablesTest tableTest = new TablesTest();
}
});
}
}
通知
tableResizeListener1 = new TableResizeListener(datatable1Table, filterPanel);
部分。这是所有表格列都连接到相应的 JPanel 元素(本示例中为 JTextField 和 JComboBox)的地方。如果您想观察没有连接元素的合成看起来如何,可以将这一行注释掉。
TableResizeListener 类。这就是问题所在。
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JTable;
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 TableResizeListener implements TableColumnModelListener {
private static final long serialVersionUID = 1L;
private JTable table = null;
private JPanel filterRow = null;
public TableResizeListener(JTable table, JPanel filterRow) {
this.table = table;
this.filterRow = filterRow;
this.table.getColumnModel().addColumnModelListener(this);
columnMarginChanged(new ChangeEvent(table.getColumnModel()));
}
// Implement TableColumnModelListener methods
// (Note: instead of implementing a listener you should be able to
// override the columnMarginChanged and columMoved methods of JTable)
@Override
public void columnMarginChanged(ChangeEvent e) {
TableColumnModel tcm = table.getColumnModel();
int columns = tcm.getColumnCount();
if(columns == filterRow.getComponentCount()) {
for (int i = 0; i < columns; i++) {
Component comp = filterRow.getComponent(i);
Dimension d = comp.getPreferredSize();
d.width = tcm.getColumn(i).getWidth();
comp.setPreferredSize(d);
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
filterRow.revalidate();
}
});
}
}
@Override
public void columnMoved(TableColumnModelEvent e) {
Component moved = filterRow.getComponent(e.getFromIndex());
filterRow.remove(e.getFromIndex());
filterRow.add(moved, e.getToIndex());
filterRow.validate();
}
@Override
public void columnAdded(TableColumnModelEvent e) {
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
}
线
filterRow.revalidate();
对这个错误负责。我尝试调用 repaint()、validate(),但是它导致视觉体验不那么流畅。
如何在不破坏视觉构图的情况下将元素连接到 JTable 外部?
【问题讨论】:
标签: java swing jtable listener