Adding multiple JProgressBar to TableColumn of JTable

跟風遠走 提交于 2019-12-17 05:12:32

问题


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);

回答1:


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;
    }
}



回答2:


To my knowledge, a renderer applies to all rows in a given column. It seems to me that you would like to apply several renderers to the same column. Furthermore, it also seems that you are attempting to give the cell renderer state.

I believe it will help to make the renderer stateless and have the renderer's method getTableCellRendererComponent() take care of setting the various (JProgressBar) properties based on values from the current row before the renderer paints the cell.

In other words, you should only need to invoke tc.setCellRenderer() once for any given column, and then have your cell renderer to draw the column for any given row (based on, say, the underlying data model for that table).



来源:https://stackoverflow.com/questions/7036036/adding-multiple-jprogressbar-to-tablecolumn-of-jtable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!