Search code examples
javaswingjtablejprogressbar

JProgressBar Animation in a Table


I have the following Problem:

I have a JTable which shows me the progress of a command. I have 2 sort of commands. Determined and indetermined commands.

If i only have indetermined progressbars in the table the progress is shown correct. but if i have one determined progressbars in it, the other indetermined wont be animated.

Here is my code:

class ProgressBarRenderer implements TableCellRenderer {

    /** The bar. */
    private JProgressBar bar = new JProgressBar() {
        public boolean isDisplayable() {
            return true;
        };
    };

    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        ProgressBarInfo pbi = (ProgressBarInfo) value;
        if (pbi.getType() == Progress.LS) {
            if (pbi.getValue() == -1) {
                bar.setIndeterminate(false);
                bar.setValue(0);
                bar.setString("Progress ended");
            } else {
                bar.setIndeterminate(true);
                bar.setString(pbi.getValue() + " " + pbi.getText());
            }
            bar.setStringPainted(true);

            return bar;
        } else if (pbi.getType() == Progress.SCP) {
            if (pbi.getValue() == -1) {
                bar.setIndeterminate(false);
                bar.setValue(0);
                bar.setString("Progress ended");
            } else {
                bar.setValue(pbi.getValue());
                bar.setString(pbi.getValue() + "% " + pbi.getText());
            }
            bar.setIndeterminate(false);
            bar.setStringPainted(true);
        }
        return bar;
    }
}

The Table is updated every 10 milliseconds by a swingworker thread, so don't mind about that.


Solution

  • The internal state of the progressBar (determinate vs. indeterminate) is very different - switching between them on the same instance might be the reason. Try to use one instance for each

    public class MyRenderer ....
        JProgressBar determinate;
        JProgressBar indeterminate; 
    
        public Component getTableCellRendererComponent(...) {
             if (value.isDeterminate) {
               ...
               return determinate;
             }
             ....
             return undeterminate
        } 
    

    Edit

    checked: it is working, though might look a bit weird with many indeterminate cells which are animated "in step". Just beware: the internal - in the ui delegate - animation state is undocumented, so there might be LAFs where it doesn't work at all (f.i. Substance, afair).