当前位置:  开发笔记 > 编程语言 > 正文

AbstractTableModel GUI显示问题

如何解决《AbstractTableModelGUI显示问题》经验,为你挑选了1个好方法。



1> trashgod..:

因为数据库访问本质上是异步的,所以您肯定希望在后台检索行以避免阻塞事件派发线程 ; SwingWorker使这相对容易.取在执行行doInBackground(),publish()中期业绩,并在你的实现添加到表模型process().此处显示了一个完整的示例,概述了随之而来的好处.该示例循环遍历文件,但您可以替换您的ResultSet操作.

while (rs.next()) {
    //collect row data
    publish(rowData);
}

tableData.add()按照您的实施process().

以下完整示例着重于自定义TableModel及其包含的交互SwingWorker,创建一个包含行的测试数据库,并显示该表的查询结果.特别是,NJTable

JDBCModel延伸AbstractTableModel.为简单起见,模型data存储在a中List,并ResultSetMetaData用于列名.作为一个更抽象的替代方案,请参阅Apache Commons DbUtils,它使用类文字作为运行时类型标记ResultSetMetaData安全地创建行数据的实例.

JDBCModel将行检索委托给私人JDBCWorker; 它publish()在从中检索的每一行上调用ResultSet; 因为process()在EDT上运行,工作人员可以优化代表父模型使用的表模型事件的数量fireTableRowsInserted().

同样,你的实现delete()应该驻留在JDBCModelGUI 中,而不是GUI; 它应该fireTableRowsDeleted()在从数据库成功删除行并从中删除之后data.

添加Thread.sleep()到worker的后台循环以查看人为增加延迟的效果.

使用setProgress()PropertyChangeListener所示,在这里,以显示进度; 一个JOptionPanedone()可能是多余的.

覆盖getPreferredScrollableViewportSize()以自定义表格封闭的大小JScrollPane.

避免使用例如TableModel与常见API名称冲突的类名.

此处检查在视图中实现实时过滤的变体.

图片

import java.awt.Dimension;
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.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;

/**
 * @see /sf/ask/17360801/
 * @see /sf/ask/17360801/
 */
public class WorkerTest {

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

    private void display() {
        JFrame f = new JFrame("WorkerTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        createTestDatabase(N);
        JDBCModel model = new JDBCModel(getConnection(), "select * from city");
        f.add(new JScrollPane(new JTable(model) {

            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(320, 240);
            }
        }));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static class Row {
        int ID;
        String name;
    }

    private static class JDBCModel extends AbstractTableModel {

        private final List 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();
                worker.execute();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

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

        @Override
        public int getColumnCount() {
            try {
                return meta.getColumnCount();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
            return 0;
        }

        @Override
        public Object getValueAt(int rowIndex, int colIndex) {
            Row row = data.get(rowIndex);
            switch (colIndex) {
                case 0:
                    return row.ID;
                case 1:
                    return row.name;
            }
            return null;
        }

        @Override
        public String getColumnName(int colIndex) {
            try {
                return meta.getColumnName(colIndex + 1);
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
            return null;
        }

        private class JDBCWorker extends SwingWorker, Row> {

            @Override
            protected List doInBackground() {
                try {
                    while (rs.next()) {
                        Row r = new Row();
                        r.ID = rs.getInt(1);
                        r.name = rs.getString(2);
                        publish(r);
                    }
                } catch (SQLException e) {
                    e.printStackTrace(System.err);
                }
                return data;
            }

            @Override
            protected void process(List chunks) {
                int n = getRowCount();
                for (Row row : chunks) {
                    data.add(row);
                }
                fireTableRowsInserted(n, n + chunks.size());
            }
        }
    }

    private static void createTestDatabase(int n) {
        Connection conn = getConnection();
        try {
            Statement st = conn.createStatement();
            st.execute("create table city(id integer, name varchar2)");
            PreparedStatement ps = conn.prepareStatement(
                "insert into city values (?, ?)");
            for (int i = 0; i < n; i++) {
                ps.setInt(1, i);
                ps.setString(2, (char) ('A' + r.nextInt(26))
                    + String.valueOf(r.nextInt(1_000_000)));
                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);
    }
}

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有