1

我有一个包含几个自定义 JXTable(JTable 的扩展)的应用程序,这些 JXTable 已更新以反映存储在数据库中的信息。

我想在表格顶部的列标题上方添加组件,这将允许用户在表格中搜索和过滤结果。目前,我已经尝试使用 JTextFields 创建一个 JPanel,这些 JTextFields 基于附加到表的 TableColumnModelListener 和附加到每个 TableColumn 的 PropertyChangeListener 添加/删除/移动和调整大小。

这是它目前的样子:

http://i.imgur.com/7bnR36y.jpg

我遇到的问题是我几乎对所有东西都使用了 jgoodies jforms 布局。在这个特定的面板中,我只是使用 BoxLayout,组件将(几乎)完美地调整大小,但是一旦我添加/删除列,就会开始推离屏幕或消失。

根据图像和我想要它做的事情,是否有人对 A)如何有效地将组件绑定到每列的位置/大小或 B)如何自定义表格的列并添加在它们之上的附加组件?

如果有帮助,这是代码:

    private final KTable table;
    private final ArrayList<Object> columnIds = new ArrayList<>();
    private final ArrayList<JTextField> filters = new ArrayList<>();

    private final PropertyChangeListener pcm = new PropertyChangeListener() {           
        @Override           
        public void propertyChange(PropertyChangeEvent evt) {              
            switch (evt.getPropertyName()) {
                case "width":
                case "preferredWidth":
                    setFilterColumnWidth((TableColumn)evt.getSource(),                   
                            (int)evt.getNewValue());
                    break;
                case "headerValue":
                    setFilterColumnName((TableColumn)evt.getSource(),                   
                            (String)evt.getNewValue());
                    break;
                case "visible":
                    setFilterColumnVisible((TableColumn)evt.getSource(),
                            (boolean)evt.getNewValue());
                    break;
                default:
                    System.out.println(evt.getPropertyName() + " : " + evt.getOldValue() + " | " + evt.getNewValue());
            }
        }       
    };

    public KTableFilterPanel(KTable table) {
        this.table = table;
        registerListeners();

        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        for (TableColumn column : table.getColumns()) {
            addFilterColumn(column);
        }
    }

    private void addFilterColumn(TableColumn column) {
        addFilterColumn(column, -1);
    }
    private void addFilterColumn(TableColumn column, int index) {
        Object id = column.getIdentifier();
        if (columnIds.contains(id))
            return;
        JTextField filter = new JTextField(column.getHeaderValue().toString());
        if (index == -1) {
            columnIds.add(id);
            filters.add(filter);
        }
        else {
            columnIds.add(index, id);
            filters.add(index, filter);
        }
        add(filter, filters.indexOf(filter));

        revalidate();
    }
    private void removeFilterColumn(TableColumn column) {
        Object id = column.getIdentifier();
        if (!columnIds.contains(id))
            return;

        removeFilterColumn(columnIds.indexOf(id));
    }
    private void removeFilterColumn(int index) {
        JTextField filter = filters.remove(index);
        columnIds.remove(index);

        remove(filter);

        revalidate();
    }    
    private void moveFilterColumn(int from, int to) {
        if (from == to)
            return;
        Object id = columnIds.remove(from);
        JTextField filter = filters.remove(from);
        if (id == null || filter == null)
            return;

        columnIds.add(to, id);
        filters.add(to, filter);

        remove(filter);
        add(filter, to);

        revalidate();
    }
    private void setFilterColumnVisible(TableColumn column, boolean visible) {
        Object id = column.getIdentifier();
        if (!columnIds.contains(id))
            return;
        filters.get(columnIds.indexOf(id)).setVisible(visible);

        revalidate();
    }    
    private void setFilterColumnWidth(TableColumn column, int width) {
        Object id = column.getIdentifier();
        if (!columnIds.contains(id))
            return;
        JTextField filter = filters.get(columnIds.indexOf(id));

        Dimension old = filter.getPreferredSize();
        filter.setPreferredSize(new Dimension(width - 40, old.height));

        revalidate();
    }
    private void setFilterColumnName(TableColumn column, String name) {

    }

    private void registerListeners() {
        table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
            @Override
            public void columnAdded(TableColumnModelEvent e) {
                TableColumn column = table.getColumnModel().getColumn(e.getToIndex());
                addFilterColumn(column);
                column.addPropertyChangeListener(pcm);
            }
            @Override
            public void columnRemoved(TableColumnModelEvent e) {
                removeFilterColumn(e.getFromIndex());
            }
            @Override
            public void columnMoved(TableColumnModelEvent e) {
                moveFilterColumn(e.getFromIndex(), e.getToIndex());
            }
            @Override
            public void columnMarginChanged(ChangeEvent e) {}
            @Override
            public void columnSelectionChanged(ListSelectionEvent e) {}
        });
    }

非常感激!

4

0 回答 0