如何 show/hide JTable 中的不同行部分
How to show/hide different row sections in a JTable
我有一个 JTable,其中的行列出了目录中的文件和文件夹。文件夹行有一个按钮,用于隐藏和显示列出文件夹中文件的行。当应用程序启动时,文件夹行之后的文件行被隐藏。在 subclass 方法中创建 table 之后,我使用 RowFilter 最初隐藏这些行:
...
public void createTable(){
//Create and populate table
...
//Add the filter to initially hide the subfile rows
TableRowSorter<DefaultTableModel> sorter = new TableRow Sorter<DefaultTableModel>(tableModel);
RowFilter hidefilter = getRowFilter();
sorter.setRowFilter(hidefilter);
myTable.setRowSorter(sorter);
}
...
private RowFilter getRowFilter() {
RowFilter<DefaultTableModel, Integer> filter = new RowFilter<DefaultTableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends DefaultTableModel, ? extends Integer> entry) {
int modelRow = entry.getIdentifier();
if(/* current row column contains a certain flag */){
//Hide the row that represents a file in the folder
return false;
}
else return true;
}
};
return filter;
}
这段代码成功地隐藏了行,但我想知道如何只显示和重新隐藏一些隐藏的行。这可以像我已经完成的那样使用过滤器 class 来完成吗?有没有一种方法可以让按钮调用过滤器函数并根据在列中找到的值进行过滤器?
基本思想是我们需要一个 Filter
class 来根据其字段值过滤条目(我只创建了一个字段以保持示例简单),并且filter 也有改变这些字段值的方法。
然后我们创建一个按钮,在按下时调用此方法,然后调用 table.getRowSorter().allRowsChanged()
,它向 table 发出数据已更改的信号,因此它必须重新绘制自身。
这是一个工作示例。
public class Test {
public static class Filter extends RowFilter<TableModel, Integer> {
private String includePrefix = "Foo";
@Override
public boolean include(
javax.swing.RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
return entry.getStringValue(0).startsWith( includePrefix );
}
// Calling this method changes the filter to allow a different prefix
public void swapPrefix() {
this.includePrefix = this.includePrefix.equals("Foo") ? "Bar" : "Foo";
}
}
public static void main(String[] args) {
//setup
JFrame frame = new JFrame();
frame.setLayout( new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
JTable table = new JTable( new Object[][]{ new Object[]{ "Foo 1" },
new Object[]{ "Bar 1" },
new Object[]{ "Foo 2" },
new Object[]{ "Foo 3" },
new Object[]{ "Bar 2" }},
new Object[] { "Foo"});
//create and configure sorter
Filter filter = new Filter();
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
sorter.setRowFilter(filter);
table.setRowSorter(sorter);
JButton changeFilter = new JButton( "Change filter");
// pressing the button changes the filter first, then tells the table sorter to update the display
changeFilter.addActionListener( e -> { filter.swapPrefix(); table.getRowSorter().allRowsChanged(); });
//display window
frame.add( table );
frame.add(changeFilter);
frame.pack();
frame.setVisible( true );
}
}
我有一个 JTable,其中的行列出了目录中的文件和文件夹。文件夹行有一个按钮,用于隐藏和显示列出文件夹中文件的行。当应用程序启动时,文件夹行之后的文件行被隐藏。在 subclass 方法中创建 table 之后,我使用 RowFilter 最初隐藏这些行:
...
public void createTable(){
//Create and populate table
...
//Add the filter to initially hide the subfile rows
TableRowSorter<DefaultTableModel> sorter = new TableRow Sorter<DefaultTableModel>(tableModel);
RowFilter hidefilter = getRowFilter();
sorter.setRowFilter(hidefilter);
myTable.setRowSorter(sorter);
}
...
private RowFilter getRowFilter() {
RowFilter<DefaultTableModel, Integer> filter = new RowFilter<DefaultTableModel, Integer>() {
@Override
public boolean include(RowFilter.Entry<? extends DefaultTableModel, ? extends Integer> entry) {
int modelRow = entry.getIdentifier();
if(/* current row column contains a certain flag */){
//Hide the row that represents a file in the folder
return false;
}
else return true;
}
};
return filter;
}
这段代码成功地隐藏了行,但我想知道如何只显示和重新隐藏一些隐藏的行。这可以像我已经完成的那样使用过滤器 class 来完成吗?有没有一种方法可以让按钮调用过滤器函数并根据在列中找到的值进行过滤器?
基本思想是我们需要一个 Filter
class 来根据其字段值过滤条目(我只创建了一个字段以保持示例简单),并且filter 也有改变这些字段值的方法。
然后我们创建一个按钮,在按下时调用此方法,然后调用 table.getRowSorter().allRowsChanged()
,它向 table 发出数据已更改的信号,因此它必须重新绘制自身。
这是一个工作示例。
public class Test {
public static class Filter extends RowFilter<TableModel, Integer> {
private String includePrefix = "Foo";
@Override
public boolean include(
javax.swing.RowFilter.Entry<? extends TableModel, ? extends Integer> entry) {
return entry.getStringValue(0).startsWith( includePrefix );
}
// Calling this method changes the filter to allow a different prefix
public void swapPrefix() {
this.includePrefix = this.includePrefix.equals("Foo") ? "Bar" : "Foo";
}
}
public static void main(String[] args) {
//setup
JFrame frame = new JFrame();
frame.setLayout( new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
JTable table = new JTable( new Object[][]{ new Object[]{ "Foo 1" },
new Object[]{ "Bar 1" },
new Object[]{ "Foo 2" },
new Object[]{ "Foo 3" },
new Object[]{ "Bar 2" }},
new Object[] { "Foo"});
//create and configure sorter
Filter filter = new Filter();
TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel());
sorter.setRowFilter(filter);
table.setRowSorter(sorter);
JButton changeFilter = new JButton( "Change filter");
// pressing the button changes the filter first, then tells the table sorter to update the display
changeFilter.addActionListener( e -> { filter.swapPrefix(); table.getRowSorter().allRowsChanged(); });
//display window
frame.add( table );
frame.add(changeFilter);
frame.pack();
frame.setVisible( true );
}
}