Search code examples
javaswingjtabletablecellrenderer

Adding multiple JProgressBar to TableColumn of JTable


I have added multiple JProgressBar to TableColumn of JTable.

I am updating all the JProgressBar with data after making certain calculations, but only the last ProgressBar(in this case ProgressBar progressObj4) which is added is getting updated.

How can I update all the ProgressBars?

The basic requirement is that I am displaying the status of file in progress bar while uploading . Currently I am hardcoding 4 progress bars to test if all the progress bars are getting update wrt the status of the file, but I need to create them dynamically. The total no of progress bars wrt the no of files which is getting uploaded. Also, how can I fetch the individual instances of the progress bars & update their status ?

I am attaching the source code of the progressbar getting added to the table column.

//tc = object of TableColumn

progressObj1 = new ProgressBarRenderer("Progress1");
progressObj1.setValue(0);
progressObj1.setStringPainted(true);
progressObj1.setBackground(Color.WHITE);
progressObj1.setBorderPainted(true);

tc.setCellRenderer(progressObj1);

progressObj2 = new ProgressBarRenderer("Progress2");
progressObj2.setValue(0);
progressObj2.setStringPainted(true);
progressObj2.setBackground(Color.WHITE);
progressObj2.setBorderPainted(true);

tc.setCellRenderer(progressObj2);

progressObj3 = new ProgressBarRenderer("Progress3");
progressObj3.setValue(0);
progressObj3.setStringPainted(true);
progressObj3.setBackground(Color.WHITE);
progressObj3.setBorderPainted(true);

tc.setCellRenderer(progressObj3);

progressObj4 = new ProgressBarRenderer("Progress4");
progressObj4.setValue(0);
progressObj4.setStringPainted(true);
progressObj4.setBackground(Color.WHITE);
progressObj4.setBorderPainted(true);

tc.setCellRenderer(progressObj4);

Solution

  • basically there are two ways move with JProgressBar by using SwingWorker and Runnable#Thread, example for SwingWorker

    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class TableCellProgressBar {
    
        private String[] columnNames = {"String", "ProgressBar"};
        private Object[][] data = {{"dummy", 100}};
        private DefaultTableModel model = new DefaultTableModel(data, columnNames) {
            private static final long serialVersionUID = 1L;
    
            @Override
            public Class<?> getColumnClass(int column) {
                return getValueAt(0, column).getClass();
            }
    
            @Override
            public boolean isCellEditable(int row, int col) {
                return false;
            }
        };
        private JTable table = new JTable(model);
    
        public JComponent makeUI() {
            TableColumn column = table.getColumnModel().getColumn(1);
            column.setCellRenderer(new ProgressRenderer());
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    startTask("test");
                    startTask("error test");
                    startTask("test");
                }
            });
            JPanel p = new JPanel(new BorderLayout());
            p.add(new JScrollPane(table));
            return p;
        }
    //http://java-swing-tips.blogspot.com/2008/03/jprogressbar-in-jtable-cell.html
    
        private void startTask(String str) {
            final int key = model.getRowCount();
            SwingWorker<Integer, Integer> worker = new SwingWorker<Integer, Integer>() {
    
                private int sleepDummy = new Random().nextInt(100) + 1;
                private int lengthOfTask = 120;
    
                @Override
                protected Integer doInBackground() {
                    int current = 0;
                    while (current < lengthOfTask && !isCancelled()) {
                        if (!table.isDisplayable()) {
                            break;
                        }
                        if (key == 2 && current > 60) { //Error Test
                            cancel(true);
                            publish(-1);
                            return -1;
                        }
                        current++;
                        try {
                            Thread.sleep(sleepDummy);
                        } catch (InterruptedException ie) {
                            break;
                        }
                        publish(100 * current / lengthOfTask);
                    }
                    return sleepDummy * lengthOfTask;
                }
    
                @Override
                protected void process(java.util.List<Integer> c) {
                    model.setValueAt(c.get(c.size() - 1), key, 1);
                }
    
                @Override
                protected void done() {
                    String text;
                    int i = -1;
                    if (isCancelled()) {
                        text = "Cancelled";
                    } else {
                        try {
                            i = get();
                            text = (i >= 0) ? "Done" : "Disposed";
                        } catch (Exception ignore) {
                            ignore.printStackTrace();
                            text = ignore.getMessage();
                        }
                    }
                    System.out.println(key + ":" + text + "(" + i + "ms)");
                }
            };
            model.addRow(new Object[]{str, 0});
            worker.execute();
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    createAndShowGUI();
                }
            });
        }
    
        public static void createAndShowGUI() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.getContentPane().add(new TableCellProgressBar().makeUI());
            frame.setSize(320, 240);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    
    class ProgressRenderer extends DefaultTableCellRenderer {
    
        private final JProgressBar b = new JProgressBar(0, 100);
    
        public ProgressRenderer() {
            super();
            setOpaque(true);
            b.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
        }
    
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            Integer i = (Integer) value;
            String text = "Completed";
            if (i < 0) {
                text = "Error";
            } else if (i < 100) {
                b.setValue(i);
                return b;
            }
            super.getTableCellRendererComponent(table, text, isSelected, hasFocus, row, column);
            return this;
        }
    }