行排序后禁用 JTableHeader 更新
Disable JTableHeader update after row sorting
我用 TableCellRenderer 自定义了一个 Jtable headers,这样过滤器图标就会出现,当用户点击过滤器图标时,一个 pop-up 过滤器像 excel's 出现(图 1)。但是,如果用户单击 header 的文本,则会应用行排序器。当应用行排序器时(图 2),它会覆盖自定义并且过滤器图标消失。有没有办法避免这种行为,同时将行排序器保持在 table header?
您可以通过使用自定义渲染器装饰 table header 的原始渲染器来实现此目的,这将添加所需的过滤图标。
例如,遵循一些代码来保留排序图标,同时在原始列旁边添加您自己的标签 header:
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.Objects;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
public class Main {
private static class MyTableCellRenderer extends DefaultTableCellRenderer {
private final TableCellRenderer originalRenderer;
public MyTableCellRenderer(final TableCellRenderer originalRenderer) {
this.originalRenderer = Objects.requireNonNull(originalRenderer);
}
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
final Component original = originalRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row >= 0) //The header will have a row equal to -1.
return original;
final JPanel container = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
final JLabel filtering = new JLabel("Filter", JLabel.CENTER); //Your icon should go in this label...
//Put some fancy background to make the positioning of the label clear:
filtering.setOpaque(true);
filtering.setBackground(Color.CYAN);
//The default renderer comes with a border... Let's apply the border to the whole new container:
if (original instanceof JComponent) {
container.setBorder(((JComponent) original).getBorder());
((JComponent) original).setBorder(null);
}
container.add(filtering);
container.add(original);
return container;
}
}
private static void createAndShowGUI() {
final JTable table = new JTable(new Object[][] {
new Object[]{"Data001", "Data002", "Data003"},
new Object[]{"Data011", "Data012", "Data013"},
new Object[]{"Data021", "Data022", "Data023"},
new Object[]{"Data031", "Data032", "Data033"},
new Object[]{"Data041", "Data042", "Data043"}
}, new Object[] {"Column1", "Column2", "Column3"});
table.setAutoCreateRowSorter(true);
final JTableHeader header = table.getTableHeader();
header.setDefaultRenderer(new MyTableCellRenderer(header.getDefaultRenderer()));
final JFrame frame = new JFrame("Table header");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(Main::createAndShowGUI);
}
}
您可以在创建的标签上使用您的图标,而不是单词 Filter(出现在每一列 header)。
参考文献:
- Source(参见部分:3. 保持排序图标)。
- How can I put a control in the JTableHeader of a JTable?
我用 TableCellRenderer 自定义了一个 Jtable headers,这样过滤器图标就会出现,当用户点击过滤器图标时,一个 pop-up 过滤器像 excel's 出现(图 1)。但是,如果用户单击 header 的文本,则会应用行排序器。当应用行排序器时(图 2),它会覆盖自定义并且过滤器图标消失。有没有办法避免这种行为,同时将行排序器保持在 table header?
您可以通过使用自定义渲染器装饰 table header 的原始渲染器来实现此目的,这将添加所需的过滤图标。
例如,遵循一些代码来保留排序图标,同时在原始列旁边添加您自己的标签 header:
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.util.Objects;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
public class Main {
private static class MyTableCellRenderer extends DefaultTableCellRenderer {
private final TableCellRenderer originalRenderer;
public MyTableCellRenderer(final TableCellRenderer originalRenderer) {
this.originalRenderer = Objects.requireNonNull(originalRenderer);
}
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
final Component original = originalRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row >= 0) //The header will have a row equal to -1.
return original;
final JPanel container = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 0));
final JLabel filtering = new JLabel("Filter", JLabel.CENTER); //Your icon should go in this label...
//Put some fancy background to make the positioning of the label clear:
filtering.setOpaque(true);
filtering.setBackground(Color.CYAN);
//The default renderer comes with a border... Let's apply the border to the whole new container:
if (original instanceof JComponent) {
container.setBorder(((JComponent) original).getBorder());
((JComponent) original).setBorder(null);
}
container.add(filtering);
container.add(original);
return container;
}
}
private static void createAndShowGUI() {
final JTable table = new JTable(new Object[][] {
new Object[]{"Data001", "Data002", "Data003"},
new Object[]{"Data011", "Data012", "Data013"},
new Object[]{"Data021", "Data022", "Data023"},
new Object[]{"Data031", "Data032", "Data033"},
new Object[]{"Data041", "Data042", "Data043"}
}, new Object[] {"Column1", "Column2", "Column3"});
table.setAutoCreateRowSorter(true);
final JTableHeader header = table.getTableHeader();
header.setDefaultRenderer(new MyTableCellRenderer(header.getDefaultRenderer()));
final JFrame frame = new JFrame("Table header");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(final String[] args) {
SwingUtilities.invokeLater(Main::createAndShowGUI);
}
}
您可以在创建的标签上使用您的图标,而不是单词 Filter(出现在每一列 header)。
参考文献:
- Source(参见部分:3. 保持排序图标)。
- How can I put a control in the JTableHeader of a JTable?