JProgressBar setValue is not working, tried with SwingUtilities as well

前端 未结 3 718
不思量自难忘°
不思量自难忘° 2020-12-19 23:10

I have implemented a JProgressBar in a JTable. I used renderer for the ProgressBar NOT EDITOR.

Now I tried to implement a ProgressBar set value but

相关标签:
3条回答
  • 2020-12-19 23:37

    Looks like you're trying to use a ProgressBar as a CellRenderer. One thing you should know, is that CellRenders are only called when a cell is being drawn, and setting values at other moments has no effect: this is because Swing uses a flyweight pattern for renderers, and thus reuses the renderer.

    To get the effect you want, you should

    • notify the table that the cell is to be updated, for instance by updating its underlying model (that will fire the necessary events), and
    • set all values you need before the getTableCellRendererComponent return, so, remove the invokeLater (the getter is called on the EDT, so you don't need to worry about threading there).
    0 讨论(0)
  • 2020-12-19 23:38

    Take a look at the Swing table tutorial: renderers and editors. The renderer uses the component to make a sort of 'stamp'. Changing the component afterwards has no effect since the component is not actually contained in your UI. That is one of the reasons you can return the same component over and over again, which would not be possible if the component was actually contained in the table. This is all explained in the linked tutorial.

    To solve your problem, just remove the SwingUtilities.invokeLater method call, and return a JProgressBar where the correct progress is set.

    And if I see this correctly, you have a TableModel containing a JProgressBar. I hope there is a good reason for this, since this is a UI component which should normally not be included on the model side. This is based on your

    final JProgressBar bar = (JProgressBar) value;
    

    call in the renderer. I would strongly suggest to take a look at your TableModel to see whether this can be avoided

    0 讨论(0)
  • 2020-12-19 23:49

    1) even is possible, don't create JComponents inside TableCellRenderer, nor re_create Object, Renderer is only for formatting cell contents

    2) use SwingWorker for moving with progress in JProgressBar (if you have real important reasons, then use Runnable#Tread)

    example about Runnable#Tread

    enter image description here

    import java.awt.Component;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JProgressBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableCellRenderer;
    
    public class TableWithProgressBars {
    
        public static class ProgressRenderer extends JProgressBar implements TableCellRenderer {
    
            private static final long serialVersionUID = 1L;
    
            public ProgressRenderer(int min, int max) {
                super(min, max);
                this.setStringPainted(true);
            }
    
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value,
                    boolean isSelected, boolean hasFocus, int row, int column) {
                this.setValue((Integer) value);
                return this;
            }
        }
        private static final int maximum = 100;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TableWithProgressBars().createGUI();
                }
            });
    
        }
    
        public void createGUI() {
            final JFrame frame = new JFrame("Progressing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Integer[] oneRow = {0, 0, 0, 0};
            String[] headers = {"One", "Two", "Three", "Four"};
            Integer[][] data = {oneRow, oneRow, oneRow, oneRow, oneRow,};
            final DefaultTableModel model = new DefaultTableModel(data, headers);
            final JTable table = new JTable(model);
            table.setDefaultRenderer(Object.class, new ProgressRenderer(0, maximum));
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            frame.add(new JScrollPane(table));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    Object waiter = new Object();
                    synchronized (waiter) {
                        int rows = model.getRowCount();
                        int columns = model.getColumnCount();
                        Random random = new Random(System.currentTimeMillis());
                        boolean done = false;
                        while (!done) {
                            int row = random.nextInt(rows);
                            int column = random.nextInt(columns);
                            Integer value = (Integer) model.getValueAt(row, column);
                            value++;
                            if (value <= maximum) {
                                model.setValueAt(value, row, column);
                                try {
                                    waiter.wait(15);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            done = true;
                            for (row = 0; row < rows; row++) {
                                for (column = 0; column < columns; column++) {
                                    if (!model.getValueAt(row, column).equals(maximum)) {
                                        done = false;
                                        break;
                                    }
                                }
                                if (!done) {
                                    break;
                                }
                            }
                        }
                        frame.setTitle("All work done");
                    }
                }
            }).start();
        }
    }
    
    0 讨论(0)
提交回复
热议问题