我正在尝试过滤包含带数字的列的JTable
中的行。
到目前为止,过滤工作正在进行,但它会对包括千位分隔符在内的数字进行过滤。例如,如果一行中有一个数字为25689的行,并且我尝试过滤此行,则必须使用“25.689”。因此,似乎在过滤之前执行了格式化。
我试图设置一个自己的默认渲染器,但是没有分隔符显示数字,但过滤是相同的。
我添加了一个重新创建问题的完整示例:
public class GroupingTest {
JFrame frame= null;
Container pane= null;
JTextField tf=null;
JXTable table=null;
public void searchTable() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
final String searchEx = "(?i)"
+ Pattern.quote(tf.getText());
final RowFilter<TableModel, Object> filter;
filter = RowFilter.regexFilter(searchEx);
table.setRowFilter(filter);
//packAll in edt
Utility.packTableView(table);
} catch (final Exception e) {
return;
}
}
});
}
public void createTable() {
frame = new JFrame();
pane=frame.getContentPane();
tf = new JTextField();
tf.setPreferredSize(new Dimension(200,25));
tf.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(final DocumentEvent e) {
searchTable();
}
@Override
public void insertUpdate(final DocumentEvent e) {
searchTable();
}
@Override
public void changedUpdate(final DocumentEvent e) {
searchTable();
}
});
String[] columnHeaders = {"long","strings"};
DefaultTableModel $model = new DefaultTableModel(columnHeaders, 0) {
@Override
public Class<?> getColumnClass(final int $col) {
if($col == 0) {
return Long.class;
} else if($col == 1){
return String.class;
} else {
return Object.class;
}
}
};
table = new JXTable($model);
table.setDefaultRenderer(Long.class, new DefaultTableCellRenderer() {
@Override
public java.awt.Component getTableCellRendererComponent(final JTable $table,
final Object $value, final boolean $isSelected, final boolean $hasFocus, final int $row,
final int $column) {
super.getTableCellRendererComponent($table, $value, $isSelected, $hasFocus, $row, $column);
if ($value instanceof Long) {
this.setHorizontalAlignment(SwingConstants.RIGHT);
}
return this;
}
});
Object[] line1 = {new Long(23345),"asdf"};
$model.addRow(line1);
Object[] line2 = {new Long(3),"dfw"};
$model.addRow(line2);
pane.add(tf,BorderLayout.NORTH);
pane.add(new JScrollPane(table),BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(300,200));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
GroupingTest gt = new GroupingTest();
gt.createTable();
}
}
答案 0 :(得分:3)
到目前为止过滤工作正在进行,但它会过滤包括千位分隔符在内的数字。
当值的格式干扰分拣机和过滤器的预期功能时,是时候检查表模型中的getColumnClass(int columnIndex)是否正在检索相应的类(在本例中为{{ 1}})。
默认Double
这种方法的实现会返回使用AbstractTableModel
方法呈现的Object.class
(这就是为什么你会看到千位分隔符)并且可能根据字符串表示。 toString()
的子类(例如AbstractTableModel
)继承此实现,因此应该覆盖此方法。例如,假设您的表格型号为DefaultTableModel
,第一列为DefaultTableModel
:
Double
有关详细信息,请参阅Sorting and Filtering教程的How to Use Tables部分。
鉴于你的新MVCE,现在很清楚你想要实现什么。我开始说我错误地假设您的表格模型包含DefaultTableModel model = new DefaultTableModel() {
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? Double.class
: super.getColumnClass(columnIndex);
}
};
而不是Double
,这对覆盖Long
方法没有任何影响(无论如何都应该这样做)但它会在最终解决方案中略有不同。
现在,要明确说明要求,您需要过滤该列:
为了实现这一目标,我使用自定义getColumnClass()
而不是像您在示例中那样使用正则表达式过滤器。这是为了控制用户键入的字符串并检查上面列出的三个条件。我设法修改了您的RowFilter
以满足要求。注意:我已将查询的字符串作为参数包含在此方法中,以便将searchTable()
文本字段保留在实现之外。请参阅以下代码:
tf
流量或多或少如下:
如果查询长度为0,则让过滤器为private void searchTable(final String query) {
RowFilter<TableModel, Integer> filter = null;
if (query.length() > 0) {
filter = new RowFilter<TableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
for (int i = 0; i < entry.getValueCount(); i++) {
String stringValue = entry.getStringValue(i);
Object entryValue = entry.getValue(i);
String numberString = entryValue instanceof Long
? String.valueOf(entryValue)
: "";
if (stringValue.contains(query) || numberString.contains(query)) {
return true;
}
}
return false;
}
};
}
table.setRowFilter(filter);
}
。这意味着表格不会被过滤,所有重试都将被包含在内。
如果不是(1)那么准备一个新的过滤器,迭代整行,询问条目 或 的字符串表示是否为entry包含查询的String。虽然那些看起来可能与他们不同,但因为Entry#getStringValue(int index)可能(实际上)检索的值不同于String#valueOf(entry#getValue(int index))。在这种情况下,第一个检索Long包括分组分隔符(或者如果您愿意,则格式化),而第二个检索Long而根本没有格式化(这意味着,没有分组分隔符)。
在任何一种情况下都将过滤器应用于表格。
我希望这个想法足够清楚。如果要过滤null
,则必须稍微调整一下,因为Double
包含十进制(不是分组)分隔符,您可能希望在检查它是否包含查询的字符串之前将其删除。