无法将 TableRowSorter 添加到 SwingWorker 生成的 JTable [英] Can't Add TableRowSorter to JTable Produced By SwingWorker

查看:56
本文介绍了无法将 TableRowSorter 添加到 SwingWorker 生成的 JTable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

感谢

代码,经测试:

import java.awt.BorderLayout;导入 java.util.concurrent.ThreadLocalRandom;导入 java.awt.EventQueue;导入 java.sql.Connection;导入 java.sql.DriverManager;导入 java.sql.PreparedStatement;导入 java.sql.ResultSet;导入 java.sql.ResultSetMetaData;导入 java.sql.SQLException;导入 java.sql.Statement;导入 java.util.ArrayList;导入 java.util.List;导入 java.util.Random;导入 javax.swing.JFrame;导入 javax.swing.JPanel;导入 javax.swing.JProgressBar;导入 javax.swing.JScrollPane;导入 javax.swing.JTable;导入 javax.swing.JTextField;导入 javax.swing.ListSelectionModel;导入 javax.swing.RowFilter;导入 javax.swing.ScrollPaneConstants;导入 javax.swing.SwingWorker;导入 javax.swing.border.EmptyBorder;导入 javax.swing.event.DocumentEvent;导入 javax.swing.event.DocumentListener;导入 javax.swing.table.AbstractTableModel;导入 javax.swing.table.TableModel;导入 javax.swing.table.TableRowSorter;/*** @see https://stackoverflow.com/q/43161033/230513* @see https://stackoverflow.com/a/34742409/230513* @see https://stackoverflow.com/a/24762078/230513*/公共类 WorkerTest {私有静态最终整数 N = 256;私有静态最终字符串 URL = "jdbc:h2:mem:test";私有静态最终随机 r = 新随机();私人 JPanel 内容窗格;私有静态 JTable tblSchedule;私人 JScrollPane scrollSchedTable;私有 JDBCModel 模型;私人 JPanel 面板;私有 JTextField 文本字段;私有静态 TableRowSorter行排序器;私人无效显示(){createTestDatabase(N);//创建测试数据库//创建图形界面JFrame f = new JFrame("WorkerTest");f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);f.setBounds(100, 100, 780, 450);contentPane = new JPanel();contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));f.setContentPane(contentPane);contentPane.setLayout(new BorderLayout(0, 0));scrollSchedTable = new JScrollPane();scrollSchedTable.setHorizo​​ntalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_​​NEVER);contentPane.add(scrollSchedTable);tblSchedule = new JTable();tblSchedule.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);tblSchedule.setShowHorizo​​ntalLines(true);tblSchedule.setShowVerticalLines(true);tblSchedule.setFillsViewportHeight(true);model = new JDBCModel(getConnection(), "select * from city");tblSchedule.setModel(模型);rowSorter = new TableRowSorter(model);tblSchedule.setRowSorter(rowSorter);scrollSchedTable.setViewportView(tblSchedule);面板 = 新 JPanel();contentPane.add(panel, BorderLayout.NORTH);panel.setLayout(new BorderLayout(0, 0));textField = new JTextField();panel.add(textField, BorderLayout.EAST);textField.setColumns(10);panel.add(model.jpb, BorderLayout.CENTER);textField.getDocument().addDocumentListener(new DocumentListener() {@覆盖公共无效插入更新(文档事件 e){String text = textField.getText().trim();if (text.trim().length() == 0) {rowSorter.setRowFilter(null);} 别的 {rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));}}@覆盖public void removeUpdate(DocumentEvent e) {String text = textField.getText();if (text.trim().length() == 0) {rowSorter.setRowFilter(null);} 别的 {rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));}}@覆盖public void changedUpdate(DocumentEvent e) {String text = textField.getText();if (text.trim().length() == 0) {rowSorter.setRowFilter(null);} 别的 {rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));}}});f.setVisible(true);}私有静态类行{字符串名称;字符串 fname;字符串 monTime;字符串 tueTime;字符串 wedTime;字符串 thuTime;字符串星期五;字符串 satTime;字符串 sunTime;字符串总时间;}私有静态类 JDBCModel 扩展 AbstractTableModel {私人最终 JProgressBar jpb = new JProgressBar();private static final long serialVersionUID = 1L;私有最终列表<行>数据 = 新的 ArrayList();私有结果集 rs = null;私有 ResultSetMetaData 元;公共 JDBCModel(连接连接,字符串查询){尝试 {语句 s = conn.createStatement();rs = s.executeQuery(查询);元 = rs.getMetaData();JDBCWorker worker = new JDBCWorker();jpb.setIndeterminate(true);worker.execute();} catch (SQLException e) {e.printStackTrace(System.err);}}@覆盖公共 int getRowCount() {返回数据大小();}@覆盖公共 int getColumnCount() {返回 10;}@覆盖公共对象 getValueAt(int rowIndex, int colIndex) {行行 = data.get(rowIndex);开关(colIndex){案例0:返回 row.lname;情况1:返回 row.fname;案例2:返回 row.monTime;案例3:返回 row.tueTime;案例4:返回 row.wedTime;案例5:返回 row.thuTime;案例6:返回 row.friTime;案例7:返回 row.satTime;案例8:返回 row.sunTime;案例9:返回 row.totalTime;}返回空;}@覆盖公共字符串 getColumnName(int colIndex) {字符串名称 = null;开关(colIndex){案例0:name = "姓氏";返回名称;情况1:name = "名字";返回名称;案例2:name = "星期一";返回名称;案例3:name = "星期二";返回名称;案例4:name = "星期三";返回名称;案例5:name = "星期四";返回名称;案例6:name = "星期五";返回名称;案例7:name = "星期六";返回名称;案例8:name = "星期日";返回名称;案例9:name = "总计";返回名称;}返回名称;}私有类 JDBCWorker 扩展了 SwingWorker, Row>{@覆盖受保护的列表<行>doInBackground() {尝试 {而(rs.next()){行 r = new Row();整数总计 = 0;r.lname = rs.getString(2);r.fname = rs.getString(1);r.monTime = String.valueOf(rs.getInt(3) + " - " + rs.getInt(4));总计 += rs.getInt(4) - rs.getInt(3);r.tueTime = String.valueOf(rs.getInt(5) + " - " + rs.getInt(6));总计 += rs.getInt(6) - rs.getInt(5);r.wedTime = String.valueOf(rs.getInt(7) + " - " + rs.getInt(8));总计 += rs.getInt(8) - rs.getInt(7);r.thuTime = String.valueOf(rs.getInt(9) + " - " + rs.getInt(10));总计 += rs.getInt(10) - rs.getInt(9);r.friTime = String.valueOf(rs.getInt(11) + " - " + rs.getInt(12));总计 += rs.getInt(12) - rs.getInt(11);r.satTime = String.valueOf(rs.getInt(13) + " - " + rs.getInt(14));总计 += rs.getInt(14) - rs.getInt(13);r.sunTime = String.valueOf(rs.getInt(15) + " - " + rs.getInt(16));总计 += rs.getInt(16) - rs.getInt(15);r.totalTime = String.valueOf(total);发布(r);}} catch (SQLException e) {e.printStackTrace(System.err);}返回数据;}@覆盖受保护的无效进程(列表<行>块){int n = getRowCount() + 1;System.out.println("行数 = " + n);System.out.println("Chunks Size = " + chunks.size());for(行行:块){数据.添加(行);}fireTableDataChanged();}@覆盖受保护的无效完成(){jpb.setIndeterminate(false);jpb.setValue(100);}}}//使用测试名称和工作时间创建测试数据库私有静态无效 createTestDatabase(int n) {ThreadLocalRandom r = ThreadLocalRandom.current();连接 conn = getConnection();尝试 {语句 st = conn.createStatement();st.execute("创建表 city(fname varchar(10), lname varchar(10), mons int(2), mone int(2), tues int(2), tuee int(2), weds int(2), wede int(2), 因此 int(2), thue int(2), fris int(2), frie int(2), sats int(2), sate int(2), suns int(2), suneint(2))");随机生成 = 新随机();PreparedStatement ps = conn.prepareStatement(插入城市值(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");for (int i = 0; i < n; i++) {ps.setString(1, "第一个" + i);ps.setString(2, "最后" + i);ps.setInt(3, r.nextInt(6, 12));ps.setInt(4, r.nextInt(13, 22));ps.setInt(5, r.nextInt(6, 12));ps.setInt(6, r.nextInt(13, 22));ps.setInt(7, r.nextInt(6, 12));ps.setInt(8, r.nextInt(13, 22));ps.setInt(9, r.nextInt(6, 12));ps.setInt(10, r.nextInt(13, 22));ps.setInt(11, r.nextInt(6, 12));ps.setInt(12, r.nextInt(13, 22));ps.setInt(13, r.nextInt(6, 12));ps.setInt(14, r.nextInt(13, 22));ps.setInt(15, r.nextInt(6, 12));ps.setInt(16, r.nextInt(13, 22));ps.执行();}} catch (SQLException ex) {ex.printStackTrace(System.err);}}私有静态连接 getConnection() {尝试 {返回 DriverManager.getConnection(URL, "", "");} catch (SQLException e) {e.printStackTrace(System.err);}返回空;}公共静态无效主(字符串 [] args){EventQueue.invokeLater(new WorkerTest()::display);}}

Thank You Hovercraft Full Of Eels for making note of the fact that my question was full of a jumbled mess of code that was unlikely to be solved. Since then, I have created a "minimal" Test Program to display the issue:

The Issue

What I am looking to do is have a GUI that displays a table containing employee information, and also allows a user to do a live search of said table by typing into a jtextfield at the top of the gui.

So I currently have a java class that creates a table and fills that table with employee information. This information is placed into the table via an SQL statement that is processed by a SwingWorker. The GUI works perfectly fine, until I try and add a TableRowSorter to the table that contains the info, this produces an error:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
    at javax.swing.DefaultRowSorter.checkAgainstModel(Unknown Source)
    at javax.swing.DefaultRowSorter.rowsInserted(Unknown Source)
    at javax.swing.JTable.notifySorter(Unknown Source)
    at javax.swing.JTable.sortedTableChanged(Unknown Source)
    at javax.swing.JTable.tableChanged(Unknown Source)
    at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
    at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown Source)
    at tesPackage.WorkerTest$JDBCModel$JDBCWorker.process(WorkerTest.java:276)

Based on this example, here's a

Working Example

package tesPackage;

import java.awt.BorderLayout;
import java.util.concurrent.ThreadLocalRandom;
import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

/**
* @see https://stackoverflow.com/a/34742409/230513
* @see https://stackoverflow.com/a/24762078/230513
*/
public class WorkerTest {

private static final int N = 25;
private static final String URL = "jdbc:h2:mem:test";
private static final Random r = new Random();

private JPanel contentPane;
private static JTable tblSchedule;
private JScrollPane scrollSchedTable;
private JDBCModel model;
private JPanel panel;
private JTextField textField;

private static TableRowSorter<TableModel> rowSorter;

private void display() {

    createTestDatabase(N);  //Create the Test Database

    //Create the GUI
    JFrame f = new JFrame("WorkerTest");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setBounds(100, 100, 780, 450);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    f.setContentPane(contentPane);
    contentPane.setLayout(new BorderLayout(0, 0));
    {
        scrollSchedTable = new JScrollPane();
        scrollSchedTable.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        contentPane.add(scrollSchedTable);
        {
            tblSchedule = new JTable();
            tblSchedule.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            tblSchedule.setShowHorizontalLines(true);
            tblSchedule.setShowVerticalLines(true);
            tblSchedule.setFillsViewportHeight(true);
            model = new JDBCModel(getConnection(), "select * from city");
            tblSchedule.setModel(model);
            rowSorter = new TableRowSorter<TableModel>(model);  //IF UNCOMMENT THESE 2 LINES GUI WILL RUN
            tblSchedule.setRowSorter(rowSorter);                //BUT IF TYPE IN SEARCH BOX THERE IS AN ERROR
            scrollSchedTable.setViewportView(tblSchedule);
        }
        {
            panel = new JPanel();
            contentPane.add(panel, BorderLayout.NORTH);
            panel.setLayout(new BorderLayout(0, 0));
            {
                textField = new JTextField();
                panel.add(textField, BorderLayout.EAST);
                textField.setColumns(10);
            }
            {
                panel.add(model.jpb, BorderLayout.CENTER);
            }
            {
                textField.getDocument().addDocumentListener(new DocumentListener(){

                    @Override
                    public void insertUpdate(DocumentEvent e) {
                        String text = textField.getText().trim();
                        if (text.trim().length() == 0) {
                            rowSorter.setRowFilter(null);
                        } else {
                            rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                        }
                    }

                    @Override
                    public void removeUpdate(DocumentEvent e) {
                        String text = textField.getText();
                        if (text.trim().length() == 0) {
                            rowSorter.setRowFilter(null);
                        } else {
                            rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                        }
                    }

                    @Override
                    public void changedUpdate(DocumentEvent e) {
                        String text = textField.getText();
                        if (text.trim().length() == 0) {
                            rowSorter.setRowFilter(null);
                        } else {
                            rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                        }
                    }

                });
            }
        }
    }
    f.setVisible(true);
}

private static class Row {
    String lname;
    String fname;
    String monTime;
    String tueTime;
    String wedTime;
    String thuTime;
    String friTime;
    String satTime;
    String sunTime;
    String totalTime;
}

private static class JDBCModel extends AbstractTableModel {

    private final JProgressBar jpb = new JProgressBar();
    private static final long serialVersionUID = 1L;
    private final List<Row> data = new ArrayList<>();
    private ResultSet rs = null;
    private ResultSetMetaData meta;

    public JDBCModel(Connection conn, String query) {
        try {
            Statement s = conn.createStatement();
            rs = s.executeQuery(query);
            meta = rs.getMetaData();
            JDBCWorker worker = new JDBCWorker();
            jpb.setIndeterminate(true);
            worker.execute();

        } catch (SQLException e) {
            e.printStackTrace(System.err);
        }
    }

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

    @Override
    public int getColumnCount() {
        return 10;
    }



    @Override
    public Object getValueAt(int rowIndex, int colIndex) {
        Row row = data.get(rowIndex);
        switch (colIndex) {
            case 0:
                return row.lname;
            case 1:
                return row.fname;
            case 2:
                return row.monTime;
            case 3:
                return row.tueTime;
            case 4:
                return row.wedTime;
            case 5:
                return row.thuTime;
            case 6:
                return row.friTime;
            case 7:
                return row.satTime;
            case 8:
                return row.sunTime;
            case 9:
                return row.totalTime;
        }
        return null;
    }

    @Override
    public String getColumnName(int colIndex) {
        String name = null;
        switch(colIndex){
        case 0: name = "Last Name";
            return name;
        case 1: name = "First Name";
            return name;
        case 2: name = "Monday";
            return name;
        case 3: name = "Tuesday";
            return name;
        case 4: name = "Wednesday";
            return name;
        case 5: name = "Thursday";
            return name;
        case 6: name = "Friday";
            return name;
        case 7: name = "Saturday";
            return name;
        case 8: name = "Sunday";
            return name;
        case 9: name = "Total";
            return name;
        }
        return name;
    }

    private class JDBCWorker extends SwingWorker<List<Row>, Row> {

        @Override
        protected List<Row> doInBackground() {
            try {
                while (rs.next()) {
                    Row r = new Row();
                    Integer total = 0;
                    r.lname = rs.getString(2);
                    r.fname = rs.getString(1);
                    r.monTime = String.valueOf(rs.getInt(3) + " - " + rs.getInt(4));
                    total += rs.getInt(4) - rs.getInt(3);
                    r.tueTime = String.valueOf(rs.getInt(5) + " - " + rs.getInt(6));
                    total += rs.getInt(6) - rs.getInt(5);
                    r.wedTime = String.valueOf(rs.getInt(7) + " - " + rs.getInt(8));
                    total += rs.getInt(8) - rs.getInt(7);
                    r.thuTime = String.valueOf(rs.getInt(9) + " - " + rs.getInt(10));
                    total += rs.getInt(10) - rs.getInt(9);
                    r.friTime = String.valueOf(rs.getInt(11) + " - " + rs.getInt(12));
                    total += rs.getInt(12) - rs.getInt(11);
                    r.satTime = String.valueOf(rs.getInt(13) + " - " + rs.getInt(14));
                    total += rs.getInt(14) - rs.getInt(13);
                    r.sunTime = String.valueOf(rs.getInt(15) + " - " + rs.getInt(16));
                    total += rs.getInt(16) - rs.getInt(15);
                    r.totalTime = String.valueOf(total);
                    publish(r);
                }
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
            return data;
        }

        @Override
        protected void process(List<Row> chunks) {
            int n = getRowCount() + 1;
            System.out.println("Row Count = " + n);
            System.out.println("Chunks Size = " + chunks.size());
            for (Row row : chunks) {
                data.add(row);
            }
            fireTableRowsInserted(n, n + chunks.size());
        }

        @Override
        protected void done(){
            jpb.setIndeterminate(false);
            jpb.setValue(100);
        }
    }
}

//Creates the Test DB with test names and working hours
private static void createTestDatabase(int n) {
    Connection conn = getConnection();
    try {
        Statement st = conn.createStatement();
        st.execute("create table city(fname varchar(10), lname varchar(10), mons int(2), mone int(2), tues int(2), tuee int(2), weds int(2), wede int(2), thus int(2), thue int(2), fris int(2), frie int(2), sats int(2), sate int(2), suns int(2), sune int(2))");
        Random gen = new Random();
        PreparedStatement ps = conn.prepareStatement(
            "insert into city values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
        for (int i = 0; i < n; i++) {
            ps.setString(1, "First" + i);
            ps.setString(2, "Last" + i);
            ps.setInt(3, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(4, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(5, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(6, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(7, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(8, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(9, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(10, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(11, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(12, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(13, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(14, ThreadLocalRandom.current().nextInt(13, 22));
            ps.setInt(15, ThreadLocalRandom.current().nextInt(6, 12));
            ps.setInt(16, ThreadLocalRandom.current().nextInt(13, 22));
            ps.execute();
        }
    } catch (SQLException ex) {
        ex.printStackTrace(System.err);
    }
}

private static Connection getConnection() {
    try {
        return DriverManager.getConnection(URL, "", "");
    } catch (SQLException e) {
        e.printStackTrace(System.err);
    }
    return null;
}

public static void main(String[] args) {
    EventQueue.invokeLater(new WorkerTest()::display);
}
}

EDIT (Only 5 Min Later)

So I started to use the debug function in eclipse and as I was stepping through the program, I found that some event called EDT.pumpOneEventForFilters(int) had a variable called arg0(it's only argument) with a value of -1. Once stepping into this event, the Exception is thrown. I'm not sure if this is useful information, but I thought I'd toss it out there just in case.

解决方案

The original example notified the listening JTable of new rows in the implementation of process():

fireTableRowsInserted(n, n + chunks.size());

Because the table needs to consider all rows when sorting and filtering, the model should notify "listeners that all cell values in the table's rows may have changed."

fireTableDataChanged();

As an aside, a single instance of ThreadLocalRandom is sufficient in createTestDatabase().

Code, as tested:

import java.awt.BorderLayout;
import java.util.concurrent.ThreadLocalRandom;
import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

/**
 * @see https://stackoverflow.com/q/43161033/230513
 * @see https://stackoverflow.com/a/34742409/230513
 * @see https://stackoverflow.com/a/24762078/230513
 */
public class WorkerTest {

    private static final int N = 256;
    private static final String URL = "jdbc:h2:mem:test";
    private static final Random r = new Random();

    private JPanel contentPane;
    private static JTable tblSchedule;
    private JScrollPane scrollSchedTable;
    private JDBCModel model;
    private JPanel panel;
    private JTextField textField;

    private static TableRowSorter<TableModel> rowSorter;

    private void display() {

        createTestDatabase(N);  //Create the Test Database

        //Create the GUI
        JFrame f = new JFrame("WorkerTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setBounds(100, 100, 780, 450);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        f.setContentPane(contentPane);
        contentPane.setLayout(new BorderLayout(0, 0));

        scrollSchedTable = new JScrollPane();
        scrollSchedTable.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        contentPane.add(scrollSchedTable);

        tblSchedule = new JTable();
        tblSchedule.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        tblSchedule.setShowHorizontalLines(true);
        tblSchedule.setShowVerticalLines(true);
        tblSchedule.setFillsViewportHeight(true);
        model = new JDBCModel(getConnection(), "select * from city");
        tblSchedule.setModel(model);
        rowSorter = new TableRowSorter<TableModel>(model);
        tblSchedule.setRowSorter(rowSorter);
        scrollSchedTable.setViewportView(tblSchedule);

        panel = new JPanel();
        contentPane.add(panel, BorderLayout.NORTH);
        panel.setLayout(new BorderLayout(0, 0));

        textField = new JTextField();
        panel.add(textField, BorderLayout.EAST);
        textField.setColumns(10);

        panel.add(model.jpb, BorderLayout.CENTER);

        textField.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                String text = textField.getText().trim();
                if (text.trim().length() == 0) {
                    rowSorter.setRowFilter(null);
                } else {
                    rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                }
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                String text = textField.getText();
                if (text.trim().length() == 0) {
                    rowSorter.setRowFilter(null);
                } else {
                    rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                }
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                String text = textField.getText();
                if (text.trim().length() == 0) {
                    rowSorter.setRowFilter(null);
                } else {
                    rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + text));
                }
            }

        });
        f.setVisible(true);
    }

    private static class Row {

        String lname;
        String fname;
        String monTime;
        String tueTime;
        String wedTime;
        String thuTime;
        String friTime;
        String satTime;
        String sunTime;
        String totalTime;
    }

    private static class JDBCModel extends AbstractTableModel {

        private final JProgressBar jpb = new JProgressBar();
        private static final long serialVersionUID = 1L;
        private final List<Row> data = new ArrayList<>();
        private ResultSet rs = null;
        private ResultSetMetaData meta;

        public JDBCModel(Connection conn, String query) {
            try {
                Statement s = conn.createStatement();
                rs = s.executeQuery(query);
                meta = rs.getMetaData();
                JDBCWorker worker = new JDBCWorker();
                jpb.setIndeterminate(true);
                worker.execute();

            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

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

        @Override
        public int getColumnCount() {
            return 10;
        }

        @Override
        public Object getValueAt(int rowIndex, int colIndex) {
            Row row = data.get(rowIndex);
            switch (colIndex) {
                case 0:
                    return row.lname;
                case 1:
                    return row.fname;
                case 2:
                    return row.monTime;
                case 3:
                    return row.tueTime;
                case 4:
                    return row.wedTime;
                case 5:
                    return row.thuTime;
                case 6:
                    return row.friTime;
                case 7:
                    return row.satTime;
                case 8:
                    return row.sunTime;
                case 9:
                    return row.totalTime;
            }
            return null;
        }

        @Override
        public String getColumnName(int colIndex) {
            String name = null;
            switch (colIndex) {
                case 0:
                    name = "Last Name";
                    return name;
                case 1:
                    name = "First Name";
                    return name;
                case 2:
                    name = "Monday";
                    return name;
                case 3:
                    name = "Tuesday";
                    return name;
                case 4:
                    name = "Wednesday";
                    return name;
                case 5:
                    name = "Thursday";
                    return name;
                case 6:
                    name = "Friday";
                    return name;
                case 7:
                    name = "Saturday";
                    return name;
                case 8:
                    name = "Sunday";
                    return name;
                case 9:
                    name = "Total";
                    return name;
            }
            return name;
        }

        private class JDBCWorker extends SwingWorker<List<Row>, Row> {

            @Override
            protected List<Row> doInBackground() {
                try {
                    while (rs.next()) {
                        Row r = new Row();
                        Integer total = 0;
                        r.lname = rs.getString(2);
                        r.fname = rs.getString(1);
                        r.monTime = String.valueOf(rs.getInt(3) + " - " + rs.getInt(4));
                        total += rs.getInt(4) - rs.getInt(3);
                        r.tueTime = String.valueOf(rs.getInt(5) + " - " + rs.getInt(6));
                        total += rs.getInt(6) - rs.getInt(5);
                        r.wedTime = String.valueOf(rs.getInt(7) + " - " + rs.getInt(8));
                        total += rs.getInt(8) - rs.getInt(7);
                        r.thuTime = String.valueOf(rs.getInt(9) + " - " + rs.getInt(10));
                        total += rs.getInt(10) - rs.getInt(9);
                        r.friTime = String.valueOf(rs.getInt(11) + " - " + rs.getInt(12));
                        total += rs.getInt(12) - rs.getInt(11);
                        r.satTime = String.valueOf(rs.getInt(13) + " - " + rs.getInt(14));
                        total += rs.getInt(14) - rs.getInt(13);
                        r.sunTime = String.valueOf(rs.getInt(15) + " - " + rs.getInt(16));
                        total += rs.getInt(16) - rs.getInt(15);
                        r.totalTime = String.valueOf(total);
                        publish(r);
                    }
                } catch (SQLException e) {
                    e.printStackTrace(System.err);
                }
                return data;
            }

            @Override
            protected void process(List<Row> chunks) {
                int n = getRowCount() + 1;
                System.out.println("Row Count = " + n);
                System.out.println("Chunks Size = " + chunks.size());
                for (Row row : chunks) {
                    data.add(row);
                }
                fireTableDataChanged();
            }

            @Override
            protected void done() {
                jpb.setIndeterminate(false);
                jpb.setValue(100);
            }
        }
    }

//Creates the Test DB with test names and working hours
    private static void createTestDatabase(int n) {
        ThreadLocalRandom r = ThreadLocalRandom.current();
        Connection conn = getConnection();
        try {
            Statement st = conn.createStatement();
            st.execute("create table city(fname varchar(10), lname varchar(10), mons int(2), mone int(2), tues int(2), tuee int(2), weds int(2), wede int(2), thus int(2), thue int(2), fris int(2), frie int(2), sats int(2), sate int(2), suns int(2), sune int(2))");
            Random gen = new Random();
            PreparedStatement ps = conn.prepareStatement(
                "insert into city values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
            for (int i = 0; i < n; i++) {
                ps.setString(1, "First" + i);
                ps.setString(2, "Last" + i);
                ps.setInt(3, r.nextInt(6, 12));
                ps.setInt(4, r.nextInt(13, 22));
                ps.setInt(5, r.nextInt(6, 12));
                ps.setInt(6, r.nextInt(13, 22));
                ps.setInt(7, r.nextInt(6, 12));
                ps.setInt(8, r.nextInt(13, 22));
                ps.setInt(9, r.nextInt(6, 12));
                ps.setInt(10, r.nextInt(13, 22));
                ps.setInt(11, r.nextInt(6, 12));
                ps.setInt(12, r.nextInt(13, 22));
                ps.setInt(13, r.nextInt(6, 12));
                ps.setInt(14, r.nextInt(13, 22));
                ps.setInt(15, r.nextInt(6, 12));
                ps.setInt(16, r.nextInt(13, 22));
                ps.execute();
            }
        } catch (SQLException ex) {
            ex.printStackTrace(System.err);
        }
    }

    private static Connection getConnection() {
        try {
            return DriverManager.getConnection(URL, "", "");
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        }
        return null;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new WorkerTest()::display);
    }
}

这篇关于无法将 TableRowSorter 添加到 SwingWorker 生成的 JTable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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