实时排序JTable [英] Live sorting of JTable

查看:62
本文介绍了实时排序JTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经弄清楚了如何正确地对JTable进行排序,但是当改变表格单元格时,我无法弄清楚如何自动更新JTable的排序顺序.现在,我有这个(很长的)代码,主要基于Java教程的如何使用表格.我强调了我对// ADDED所做的更改.在这种情况下,新添加的值可以正确排序,但是当我进入编辑值时,即使我调用fireTableCellUpdated?

I've figured out how to get a JTable to be sorted properly, but I can't figure out how to get it to automatically update the sort order when a table cell is changed. Right now, I have this (admittedly long) code, mostly based on that in the Java Tutorial's How to Use Tables. I've highlighted the changes I've made with // ADDED. In this case, newly-added values sort properly, but when I go in to edit a value, it doesn't seem to resort, even though I call fireTableCellUpdated?

简而言之,当模型中的数据值更改时,如何使表重新排序?

In short, how can I get a table to re-sort when a data value changes in the model?

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 * See the standard BSD license.
 */ 

package components;

/*
 * TableSortDemo.java requires no other files.
 */

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

public class TableSortDemo extends JPanel {
    private boolean DEBUG = false;

    public TableSortDemo() {
        super();
        setLayout(new BoxLayout(TableSortDemo.this, BoxLayout.PAGE_AXIS));
        final MyTableModel m = new MyTableModel();
        JTable table = new JTable(m);
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setFillsViewportHeight(true);
        table.setAutoCreateRowSorter(true);

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);

        //Add the scroll pane to this panel.
        add(scrollPane);

        // ADDED: button to add a value
        JButton addButton = new JButton("Add a new value");
        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                m.addValue(
                        JOptionPane.showInputDialog(
                                TableSortDemo.this, "Value?"));
            }
        });

        // ADDED button to change a value
        JButton setButton = new JButton("Change a value");
        setButton.addActionListener(new ActionListener() {
            /* (non-Javadoc)
             * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
             */
            public void actionPerformed(ActionEvent e) {
                m.setValueAt(
                        JOptionPane.showInputDialog(
                                TableSortDemo.this, "Value?"),
                        Integer.parseInt(
                                JOptionPane.showInputDialog(
                                        TableSortDemo.this, "Which?")), 0);
            }
        });
        add(addButton);
        add(setButton);
    }

    class MyTableModel extends AbstractTableModel {
        private static final long serialVersionUID = -7053335255134714625L;
        private String[] columnNames = {"Column"};
        // ADDED data as mutable ArrayList
        private ArrayList<String> data = new ArrayList<String>();

        public MyTableModel() {
            data.add("Anders");
            data.add("Lars");
            data.add("Betty");
            data.add("Anna");
            data.add("Jon");
            data.add("Zach");
        }

        // ADDED
        public void addValue(Object v) {
            data.add(v.toString());
            int row = data.size() - 1;
            fireTableRowsInserted(row, row);
        }

        public int getColumnCount() {
            return columnNames.length;
        }

        public int getRowCount() {
            return data.size();
        }

        public String getColumnName(int col) {
            return columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return data.get(row) + " " + row;
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class<String> getColumnClass(int c) {
            return String.class;
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }

        /*
         * Don't need to implement this method unless your table's
         * data can change.
         */
        public void setValueAt(Object value, int row, int col) {
            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                                   + " to " + value
                                   + " (an instance of "
                                   + value.getClass() + ")");
            }

            data.set(row, value.toString());

            // ADDED: uncommented this line, despite warnings to the contrary
            fireTableCellUpdated(row, col);

            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }

        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();

            for (int i=0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j=0; j < numCols; j++) {
                    System.out.print("  " + data.get(i));
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("TableSortDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TableSortDemo newContentPane = new TableSortDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

推荐答案

采取了两步解决方案:

首先,我使用Tablesorter而不是autoCreateRowSorter来对数据更改进行排序:

First I had the TableSorter sort on data change, by using this rather than autoCreateRowSorter:

sorter = new TableRowSorter<MyTableModel>(m);
table.setRowSorter(sorter);
sorter.setSortsOnUpdates(true);

然后,我不得不更改更新方法以更新整个表. fireTableCellUpdatedfireTableRowsUpdated只会重绘已更新的特定行,而不是整个表(这意味着您将得到一个重复出现的条目,该条目在稍后被重绘后会立即更改.因此,我更改了

Then, I had to change the update method to update the entire table. The fireTableCellUpdated and the fireTableRowsUpdated would only redraw the specific rows that were updated, not the entire table (meaning you'd get a duplicate-appearing entry that changed as soon as it was redrawn later. So, I changed

fireTableCellUpdated(row, col);

fireTableRowsUpdated(0, data.size() - 1);

现在,即使发生数据更改,它也可以正确排序,并且保留选择.

and now it sorts properly, even upon data changes, and selection is preserved.

这篇关于实时排序JTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆