我有一个应用程序,其中包含多个自定义JXTable(JTable的扩展),它们会更新以反映存储在数据库中的信息。
我想在表格的顶部添加组件,在列标题上方,这将允许用户在表格中搜索和过滤结果。目前,我已经尝试创建一个带有JTextField的JPanel,它们根据附加到表的TableColumnModelListener添加/删除/移动和调整大小,并附加到每个TableColumn的PropertyChangeListener。
目前的情况如下:
我遇到的问题是我使用jgoodies jforms布局几乎所有东西。在这个特定的面板中,我只是使用BoxLayout,组件将调整(几乎)完美,但是一旦我添加/删除列,就开始推离屏幕或消失。
基于图像以及我想要它做什么,是否有人建议A)如何有效地将组件绑定到每列的位置/大小,或B)如何自定义表的列他们自己并在他们之上添加其他组件?
如果有帮助的话,这是代码:
private final KTable table;
private final ArrayList<Object> columnIds = new ArrayList<>();
private final ArrayList<JTextField> filters = new ArrayList<>();
private final PropertyChangeListener pcm = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
switch (evt.getPropertyName()) {
case "width":
case "preferredWidth":
setFilterColumnWidth((TableColumn)evt.getSource(),
(int)evt.getNewValue());
break;
case "headerValue":
setFilterColumnName((TableColumn)evt.getSource(),
(String)evt.getNewValue());
break;
case "visible":
setFilterColumnVisible((TableColumn)evt.getSource(),
(boolean)evt.getNewValue());
break;
default:
System.out.println(evt.getPropertyName() + " : " + evt.getOldValue() + " | " + evt.getNewValue());
}
}
};
public KTableFilterPanel(KTable table) {
this.table = table;
registerListeners();
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
for (TableColumn column : table.getColumns()) {
addFilterColumn(column);
}
}
private void addFilterColumn(TableColumn column) {
addFilterColumn(column, -1);
}
private void addFilterColumn(TableColumn column, int index) {
Object id = column.getIdentifier();
if (columnIds.contains(id))
return;
JTextField filter = new JTextField(column.getHeaderValue().toString());
if (index == -1) {
columnIds.add(id);
filters.add(filter);
}
else {
columnIds.add(index, id);
filters.add(index, filter);
}
add(filter, filters.indexOf(filter));
revalidate();
}
private void removeFilterColumn(TableColumn column) {
Object id = column.getIdentifier();
if (!columnIds.contains(id))
return;
removeFilterColumn(columnIds.indexOf(id));
}
private void removeFilterColumn(int index) {
JTextField filter = filters.remove(index);
columnIds.remove(index);
remove(filter);
revalidate();
}
private void moveFilterColumn(int from, int to) {
if (from == to)
return;
Object id = columnIds.remove(from);
JTextField filter = filters.remove(from);
if (id == null || filter == null)
return;
columnIds.add(to, id);
filters.add(to, filter);
remove(filter);
add(filter, to);
revalidate();
}
private void setFilterColumnVisible(TableColumn column, boolean visible) {
Object id = column.getIdentifier();
if (!columnIds.contains(id))
return;
filters.get(columnIds.indexOf(id)).setVisible(visible);
revalidate();
}
private void setFilterColumnWidth(TableColumn column, int width) {
Object id = column.getIdentifier();
if (!columnIds.contains(id))
return;
JTextField filter = filters.get(columnIds.indexOf(id));
Dimension old = filter.getPreferredSize();
filter.setPreferredSize(new Dimension(width - 40, old.height));
revalidate();
}
private void setFilterColumnName(TableColumn column, String name) {
}
private void registerListeners() {
table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
@Override
public void columnAdded(TableColumnModelEvent e) {
TableColumn column = table.getColumnModel().getColumn(e.getToIndex());
addFilterColumn(column);
column.addPropertyChangeListener(pcm);
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
removeFilterColumn(e.getFromIndex());
}
@Override
public void columnMoved(TableColumnModelEvent e) {
moveFilterColumn(e.getFromIndex(), e.getToIndex());
}
@Override
public void columnMarginChanged(ChangeEvent e) {}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {}
});
}
非常感谢!