我使用 TableCellRenderer 自定義了一個 Jtable 標題,因此會出現過濾器圖示,并且當用戶單擊過濾器圖示時,會出現類似 excel 的彈出過濾器(圖 1)。但是,如果用戶單擊標題的文本,則會應用行排序器。當應用行排序器(圖 2)時,它會覆寫自定義并且過濾器圖示消失。有沒有辦法在將行排序器保留在表頭上的同時避免這種行為?


uj5u.com熱心網友回復:
您可以通過使用自定義渲染器裝飾表頭的原始渲染器來完成此操作,該渲染器將添加所需的過濾圖示。
例如,遵循一些代碼來保留排序圖示,同時在原始列標題旁邊添加您自己的標簽:
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);
}
}
您可以使用創建的標簽上的圖示代替過濾器一詞(出現在每個列標題上)。
參考:
- 來源(參見章節:3. 保留排序圖示)。
- 如何在 JTable 的 JTableHeader 中放置控制元件?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/473175.html
上一篇:JavaSwing:如何使setFileFilter()在FileChooser設定的目錄之外作業
下一篇:直到滑鼠懸停按鈕才可見
