将进度条添加到每个表单元格以进行文件进度 – Java

当您点击加密时,应用程序会加密放入表中的每个文件,并且我想在显示加密文件时的进度. “状态”列将从“未处理”更改为“已处理”.

类似于您在电子邮件中附加多个文件的方式.我一直在研究细胞渲染器和ProgressBarTablecell,但不确定如何去实现它们.任何帮助赞赏.我正在张贴表.

import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Point;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.dnd.DnDConstants;
    import java.awt.dnd.DropTarget;
    import java.awt.dnd.DropTargetDragEvent;
    import java.awt.dnd.DropTargetDropEvent;
    import java.io.File;
    import java.io.IOException;
    import java.util.List;

    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.table.DefaultTableModel;

    public class DropTable {

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

        public DropTable() {
            EventQueue.invokelater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager
                                .getSystemLookAndFeelClassName());//get look and feel of whatever OS we're using
                    } catch (ClassNotFoundException | InstantiationException
                            | illegalaccessexception
                            | UnsupportedLookAndFeelException ex) {
                    }

                    JFrame frame = new JFrame();
                    frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new DropPane());
                    frame.pack();
                    frame.setLocationRelativeto(null);
                    frame.setVisible(true);
                }

            });
        }

        public class DropPane extends JPanel {

            /**
             * 
             */
            private static final long serialVersionUID = 1L;
            private JTable table;
            private JScrollPane scroll;
            private DefaultTableModel tm = new DefaultTableModel(new String[] {
                    "File","File Type","Size","Status" },0);

            public DropPane() {
                table = new JTable();
                table.setShowGrid(true);
                table.setShowHorizontalLines(true);
                table.setShowVerticalLines(true);
                table.setGridColor(Color.GRAY);


                table.setModel(tm);
                table.setFillsViewportHeight(true);
                table.setPreferredSize(new Dimension(500,300));

                scroll = new JScrollPane(table);

                table.setDropTarget(new DropTarget() {
                    @Override
                    public synchronized void dragOver(DropTargetDragEvent dtde) {
                        Point point = dtde.getLocation();
                        int row = table.rowAtPoint(point);
                        if (row < 0) {
                            table.clearSelection();
                        } else {
                            table.setRowSelectionInterval(row,row);
                        }
                        dtde.acceptDrag(DnDConstants.ACTION_copY_OR_MOVE);
                    }

                    @Override
                    public synchronized void drop(DropTargetDropEvent dtde) {
                        if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
                        {//make sure the flavors are files
                            dtde.acceptDrop(DnDConstants.ACTION_copY_OR_MOVE);//dndconstants tells what to do with the drag files
                            //change to ACTION_copY so it removes the file from the directory
                            Transferable t = dtde.getTransferable();
                            List fileList = null;
                            try {
                                fileList = (List) t.getTransferData(DataFlavor.javaFileListFlavor);//get file
                                if (fileList.size() > 0) {
                                    table.clearSelection();
                                    Point point = dtde.getLocation();//point is (x,y) 
                                    int row = table.rowAtPoint(point);
                                    DefaultTableModel model = (DefaultTableModel) table.getModel();
                                    for (Object value : fileList) {
                                        if (value instanceof File) {
                                            File f = (File) value;

                                            if (row < 0) {//insert rows into the right columns
                                            model.addRow(new Object[]{f.getAbsolutePath(),"",f.length(),""});//path under "File"
                                            } else {
                                                model.insertRow(row,new Object[]{f.getAbsolutePath(),""});//get size of file
                                                row++;

                                            }
                                        }
                                    }
                                }
                            } catch (UnsupportedFlavorException e) {
                                e.printstacktrace();
                            } catch (IOException e) {
                                e.printstacktrace();
                            }
                        } else {
                            dtde.rejectDrop();
                        }
                    }

                });

                add(scroll,BorderLayout.CENTER);
            }
        }
    }

解决方法

这是一个基本的例子,它基本上使用SwingWorker扫描驱动器的根目录并列出所有文件.一旦完成,它将尝试读取每个文件,在它自己的SwingWorker更新表,因为它.

免责声明:这是一个例子.我使用Thread.sleep轻轻地减慢读取,忽略缓冲区和其他一些事情,我会在生产代码中做不同的,但我想强调进度更新.

怎么运行的

首先,您需要一个能够显示进度更新的单元格渲染器.我选择了一个简单的自定义JProgressBar,但你可能会喜欢一些更复杂的东西.

您需要一些方法来更新表模型.我选择提供一个简单的updateStatus方法,传递我正在更新的文件,这允许我使用内部查找来查找相关行.然后我使用setValueAt方法来更新行对象.这不是真正需要的,但是我想演示使用setValueAt方法,您可以直接从updateStatus方法更新行对象.

最后,通知表中对模型的更改,以便它会自动重绘.

public class UpdateTable {

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

    public UpdateTable() {
        EventQueue.invokelater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | illegalaccessexception | UnsupportedLookAndFeelException ex) {
                }

                UpdatableTableModel model = new UpdatableTableModel();

                JTable table = new JTable();
                table.setModel(model);

                table.getColumn("Status").setCellRenderer(new ProgressCellRender());

                JFrame frame = new JFrame();
                frame.setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeto(null);
                frame.setVisible(true);

                FileFinderWorker worker = new FileFinderWorker(model);
                worker.execute();

            }
        });
    }

    public class ProgressCellRender extends JProgressBar implements TableCellRenderer {

        @Override
        public Component getTableCellRendererComponent(JTable table,Object value,boolean isSelected,boolean hasFocus,int row,int column) {
            int progress = 0;
            if (value instanceof Float) {
                progress = Math.round(((Float) value) * 100f);
            } else if (value instanceof Integer) {
                progress = (int) value;
            }
            setValue(progress);
            return this;
        }
    }

    public class RowData {

        private File file;
        private String type;
        private long length;
        private float status;

        public RowData(File file,String type) {
            this.file = file;
            this.type = type;
            this.length = file.length();
            this.status = 0f;
        }

        public File getFile() {
            return file;
        }

        public long getLength() {
            return length;
        }

        public float getStatus() {
            return status;
        }

        public String getType() {
            return type;
        }

        public void setStatus(float status) {
            this.status = status;
        }
    }

    public class UpdatableTableModel extends AbstractTableModel {

        private List<RowData> rows;
        private Map<File,RowData> mapLookup;

        public UpdatableTableModel() {
            rows = new ArrayList<>(25);
            mapLookup = new HashMap<>(25);
        }

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

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

        @Override
        public String getColumnName(int column) {
            String name = "??";
            switch (column) {
                case 0:
                    name = "File";
                    break;
                case 1:
                    name = "File Type";
                    break;
                case 2:
                    name = "Size";
                    break;
                case 3:
                    name = "Status";
                    break;
            }
            return name;
        }

        @Override
        public Object getValueAt(int rowIndex,int columnIndex) {
            RowData rowData = rows.get(rowIndex);
            Object value = null;
            switch (columnIndex) {
                case 0:
                    value = rowData.getFile();
                    break;
                case 1:
                    value = rowData.getType();
                    break;
                case 2:
                    value = rowData.getLength();
                    break;
                case 3:
                    value = rowData.getStatus();
                    break;
            }
            return value;
        }

        @Override
        public void setValueAt(Object aValue,int rowIndex,int columnIndex) {
            RowData rowData = rows.get(rowIndex);
            switch (columnIndex) {
                case 3:
                    if (aValue instanceof Float) {
                        rowData.setStatus((float) aValue);
                    }
                    break;
            }
        }

        public void addFile(File file) {
            RowData rowData = new RowData(file,"A File");
            mapLookup.put(file,rowData);
            rows.add(rowData);
            fireTableRowsInserted(rows.size() - 1,rows.size() - 1);
        }

        protected void updateStatus(File file,int progress) {
            RowData rowData = mapLookup.get(file);
            if (rowData != null) {
                int row = rows.indexOf(rowData);
                float p = (float) progress / 100f;
                setValueAt(p,row,3);
                fireTableCellUpdated(row,3);
            }
        }
    }

    public class FileFinderWorker extends SwingWorker<List<File>,File> {

        private UpdatableTableModel model;

        public FileFinderWorker(UpdatableTableModel model) {
            this.model = model;
        }

        @Override
        protected void process(List<File> chunks) {
            for (File file : chunks) {
                model.addFile(file);
            }
        }

        @Override
        protected List<File> doInBackground() throws Exception {
            File files[] = new File(System.getProperty("user.dir")).listFiles();
            List<File> lstFiles = new ArrayList<>(Arrays.asList(files));
            for (File file : lstFiles) {
                // You Could actually publish the entire array,but I'm doing this
                // deliberatly ;)
                publish(file);
            }
            return lstFiles;
        }

        @Override
        protected void done() {
            try {
                List<File> files = get();
                for (File file : files) {
                    new FileReaderWorker(model,file).execute();
                }
            } catch (Exception exp) {
                exp.printstacktrace();
            }
        }
    }

    public class FileReaderWorker extends SwingWorker<File,File> {

        private File currentFile;
        private UpdatableTableModel model;

        public FileReaderWorker(UpdatableTableModel model,File file) {
            this.currentFile = file;
            this.model = model;

            addPropertychangelistener(new Propertychangelistener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if (evt.getPropertyName().equals("progress")) {
                        FileReaderWorker.this.model.updateStatus(currentFile,(int) evt.getNewValue());
                    }
                }
            });

        }

        @Override
        protected File doInBackground() throws Exception {
            if (currentFile.isFile()) {
                setProgress(0);
                long fileLength = currentFile.length();
                BufferedReader reader = null;
                char[] cbuf = new char[1024];
                try {
                    reader = new BufferedReader(new FileReader(currentFile));
                    int bytesRead = -1;
                    int totalBytesRead = 0;
                    while ((bytesRead = reader.read(cbuf)) != -1) {
                        totalBytesRead += bytesRead;
                        int progress = (int) Math.round(((double) totalBytesRead / (double) fileLength) * 100d);
                        setProgress(progress);
                        Thread.sleep(25);
                    }
                    setProgress(100);
                } catch (Exception e) {
                    e.printstacktrace();
                    setProgress(100);
                } finally {
                    try {
                        reader.close();
                    } catch (Exception e) {
                    }
                }
            } else {
                setProgress(100);
            }
            return currentFile;
        }
    }
}

重要概念.

永远,EVER阻止任何长时间运行的事件调度线程.相反,将这些耗时的操作移动到后台线程中.在这里,我使用了SwingWorker

阅读Concurrency in Swing了解更多信息

相关文章

应用场景 C端用户提交工单、工单创建完成之后、会发布一条工...
线程类,设置有一个公共资源 package cn.org.chris.concurre...
Java中的数字(带有0前缀和字符串)
在Java 9中使用JLink的目的是什么?
Java Stream API Filter(过滤器)
在Java中找到正数和负数数组元素的数量