排序后禁用JTableHeader更新

发布于 2025-01-25 20:23:11 字数 510 浏览 3 评论 0原文

我定制了一个带有tablecellrenderer的JTable标头,因此会出现过滤器图标,并且当用户单击过滤器图标时,出现像Excel的弹出滤镜(图1)。但是,如果用户单击标题的文本,则使用了一个行分落器。当应用行选拔器(图2)时,它覆盖自定义和过滤器图标消失。是否有一种方法可以避免在将行分隔器保存在桌标题上的同时?

”在此处输入图像说明”

I customized a Jtable headers with a TableCellRenderer so filter icon would appear, and as the user clicks on the filter icon, a pop-up filter like excel's appears (picture 1). However, if the user clicks on the text of the header, a row sorter is appliead. When the row sorter is applied (picture 2), it override the customization and filter icon disappears. Is there a way to avoid this behavior while keeping the row sorter on the table header?

enter image description here

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒与心事 2025-02-01 20:23:11

您可以通过使用自定义渲染标头的原始渲染器进行装饰,从而添加所需的过滤图标。

例如,遵循一些代码在原始列标头旁边添加自己的标签时保留排序图标:

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 (显示在每个列标题上)您可以在改为创建标签。

参考:

  1. source部分: 3。
  2. 我如何在JTable的JTableHeader?

You can do this by decorating the original renderer of the table header with a custom one which will add the desired icon of filtering.

For example, follows some code to preserve the sort icons while adding your own label next to the original column 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);
    }
}

Instead of the word Filter (which appears on each column header) you can use your icons on the created label instead.

References:

  1. Source (see the section: 3. Keeping sort icons).
  2. How can I put a control in the JTableHeader of a JTable?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文