Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 巨大数据负载下对JTable行选择事件的延迟响应_Java_Swing - Fatal编程技术网

Java 巨大数据负载下对JTable行选择事件的延迟响应

Java 巨大数据负载下对JTable行选择事件的延迟响应,java,swing,Java,Swing,我有一个SwingJTable动态更新,其中包含大量数据。新行不断地实时添加,在几分钟内可以添加大约1000-2000行。我已经注册了一个监听器来响应使用的单行选择事件来执行一些操作。我使用了Observer模式进行Swing数据绑定,表的模型由WritableList实现支持。因此,新项从表自身的领域添加到表中。侦听器是从SWT UI线程添加的。 问题是,当向表中添加新行时,它不会立即响应用户行选择事件。只有在停止更新表格模型时,表格才会根据用户选择做出响应—有时延迟超过30-60秒。 请帮助

我有一个Swing
JTable
动态更新,其中包含大量数据。新行不断地实时添加,在几分钟内可以添加大约1000-2000行。我已经注册了一个监听器来响应使用的单行选择事件来执行一些操作。我使用了Observer模式进行Swing数据绑定,表的模型由WritableList实现支持。因此,新项从表自身的领域添加到表中。侦听器是从SWT UI线程添加的。 问题是,当向表中添加新行时,它不会立即响应用户行选择事件。只有在停止更新表格模型时,表格才会根据用户选择做出响应—有时延迟超过30-60秒。 请帮助我理解为什么我的表模型在集中更新时不会立即响应用户选择,以及如何克服此限制。
如果您有任何建议,我们将不胜感激。

请在后台的行中使用
SwingWorker
,并在
过程()的实现中更新
表格模型<代码>SwingWorker
将以可持续的速率更新。以确保您没有阻塞

附录:GUI对这1000000行保持响应,如测试所示。分析时,请注意,每次单击“Go”按钮都会启动一个新的工作进程

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;

/** @see https://stackoverflow.com/a/17415635/230513 */
public class TestTableLoad01 {

    public static void main(String[] args) {
        new TestTableLoad01();
    }

    public TestTableLoad01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                final MyTableModel model = new MyTableModel();
                JTable table = new JTable(model);
                table.setDefaultRenderer(Date.class, new TimeCellRenderer());

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.add(new JButton(new AbstractAction("Go") {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        TableSwingWorker worker = new TableSwingWorker(model);
                        worker.execute();
                    }
                }), BorderLayout.SOUTH);
            }
        });
    }

    public class TimeCellRenderer extends DefaultTableCellRenderer {

        private DateFormat df;

        public TimeCellRenderer() {
            df = new SimpleDateFormat("HH:mm:ss");
        }

        @Override
        public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row, int column) {

            if (value instanceof Date) {

                value = df.format(value);

            }

            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            return this;

        }
    }

    public class MyTableModel extends AbstractTableModel {

        private String[] columnNames = new String[]{"Date", "Row"};
        private List<RowData> data;

        public MyTableModel() {
            data = new ArrayList<RowData>(25);
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return columnIndex == 0 ? Date.class : Integer.class;
        }

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

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

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

        @Override
        public Object getValueAt(int row, int col) {
            RowData value = data.get(row);
            return col == 0 ? value.getDate() : value.getRow();
        }

        public void addRow(RowData value) {
            int rowCount = getRowCount();
            data.add(value);
            fireTableRowsInserted(rowCount, rowCount);
        }

        public void addRows(RowData... value) {
            addRows(Arrays.asList(value));
        }

        private void addRows(List<RowData> rows) {
            int rowCount = getRowCount();
            data.addAll(rows);
            fireTableRowsInserted(rowCount, getRowCount() - 1);
        }
    }

    public class RowData {

        private Date date;
        private int row;

        public RowData(int row) {
            this.date = new Date();
            this.row = row;
        }

        public Date getDate() {
            return date;
        }

        public int getRow() {
            return row;
        }
    }

    public class TableSwingWorker extends SwingWorker<MyTableModel, RowData> {

        private final MyTableModel tableModel;

        public TableSwingWorker(MyTableModel tableModel) {
            this.tableModel = tableModel;
        }

        @Override
        protected MyTableModel doInBackground() throws Exception {

            // This is a deliberate pause to allow the UI time to render
            Thread.sleep(1000);

            System.out.println("Start polulating");

            for (int index = 0; index < 1000000; index++) {

                RowData data = new RowData(index);
                publish(data);
                Thread.yield();
            }
            return tableModel;
        }

        @Override
        protected void process(List<RowData> chunks) {
            System.out.println("Adding " + chunks.size() + " rows");
            tableModel.addRows(chunks);
        }
    }
}
导入java.awt.BorderLayout;
导入java.awt.Component;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.text.DateFormat;
导入java.text.simpleDataFormat;
导入java.util.ArrayList;
导入java.util.array;
导入java.util.Date;
导入java.util.List;
导入javax.swing.AbstractAction;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.SwingWorker;
导入javax.swing.table.AbstractTableModel;
导入javax.swing.table.DefaultTableCellRenderer;
/**@见https://stackoverflow.com/a/17415635/230513 */
公共类TestTableLoad01{
公共静态void main(字符串[]args){
新的TestTableLoad01();
}
公共TestTableLoad01(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
最终MyTableModel模型=新的MyTableModel();
JTable table=新的JTable(模型);
table.setDefaultRenderer(Date.class,new TimeCellRenderer());
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(新的BorderLayout());
frame.add(新的JScrollPane(表));
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
frame.add(新的JButton(新的抽象动作(“Go”){
@凌驾
已执行的公共无效操作(操作事件e){
TableSwingWorker=新的TableSwingWorker(型号);
worker.execute();
}
}),边界布局(南部);
}
});
}
公共类TimeCellRenderer扩展了DefaultTableCellRenderer{
专用数据格式df;
公共计时器(){
df=新的简化格式(“HH:mm:ss”);
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表,
对象值,布尔值为选定,布尔值为焦点,整数行,整数列){
if(值instanceof Date){
值=df.格式(值);
}
getTableCellRenderComponent(表、值、isSelected、hasFocus、行、列);
归还这个;
}
}
公共类MyTableModel扩展了AbstractTableModel{
私有字符串[]columnNames=新字符串[]{“日期”,“行”};
私人名单数据;
公共MyTableModel(){
数据=新阵列列表(25);
}
@凌驾
公共类getColumnClass(int columnIndex){
return columnIndex==0?Date.class:Integer.class;
}
@凌驾
公共字符串getColumnName(int-col){
返回列名[col];
}
@凌驾
public int getColumnCount(){
返回columnNames.length;
}
@凌驾
public int getRowCount(){
返回data.size();
}
@凌驾
公共对象getValueAt(整数行,整数列){
RowData值=data.get(行);
返回列==0?value.getDate():value.getRow();
}
public void addRow(行数据值){
int rowCount=getRowCount();
数据增值;
fireTableRowsInserted(rowCount,rowCount);
}
public void addRows(RowData…值){
addRows(Arrays.asList(value));
}
私有void addRows(列表行){
int rowCount=getRowCount();
data.addAll(行);
fireTableRowsInserted(rowCount,getRowCount()-1);
}
}
公共类行数据{
私人日期;
私人int row;
公共行数据(int行){
this.date=新日期();
this.row=行;
}
公共日期getDate(){
返回日期;
}
public int getRow(){
返回行;
}
}
公共类TableSwingWorker扩展了SwingWorker{
私有最终MyTableModel tableModel;
公共表WingWorker(MyTableModel tableModel){
this.tableModel=tableModel;
}
@凌驾
受保护的MyTableModel doInBackground()引发异常{
//这是一个故意的暂停,以允许UI有时间渲染
睡眠(1000);
System.out.println(“开始编程”);
对于(int index=0;index<1000000;index++){