6 votes

Ajout de plusieurs JProgressBar à la colonne TableColumn de JTable

J'ai ajouté plusieurs JProgressBar a TableColumn de JTable .

Je mets à jour toutes les barres de progression JProgressBar avec des données après avoir effectué certains calculs, mais seule la dernière barre de progression JProgressBar est mise à jour. ProgressBar (dans ce cas ProgressBar progressObj4 ) qui est ajouté est mis à jour.

Comment puis-je mettre à jour tous les ProgressBar s ?

L'exigence de base est que j'affiche l'état du fichier dans la barre de progression pendant le téléchargement. Actuellement, je code en dur 4 barres de progression pour tester si toutes les barres de progression sont mises à jour par rapport à l'état du fichier, mais j'ai besoin de les créer dynamiquement. Le nombre total de barres de progression par rapport au nombre de fichiers qui sont téléchargés. De plus, comment puis-je récupérer les instances individuelles des barres de progression et mettre à jour leur statut ?

Je joins le code source de la barre de progression qui est ajoutée à la colonne du tableau.

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

8voto

mKorbel Points 90340

En fait, il y a deux façons de bouger avec JProgressBar en utilisant SwingWorker et Runnable#Thread, exemple pour 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;
    }
}

3voto

sbrattla Points 2351

A ma connaissance, un moteur de rendu s'applique à toutes les lignes d'une colonne donnée. Il me semble que vous souhaitez appliquer plusieurs moteurs de rendu à une même colonne. De plus, il semble également que vous essayez de donner un état au rendu de la cellule.

Je pense qu'il serait utile de rendre le moteur de rendu sans état et de faire en sorte que la méthode getTableCellRendererComponent() du moteur de rendu se charge de définir les diverses propriétés (JProgressBar) en fonction des valeurs de la ligne actuelle avant que le moteur de rendu ne peigne la cellule.

En d'autres termes, il vous suffit d'invoquer tc.setCellRenderer() une seule fois pour une colonne donnée, puis de faire en sorte que votre moteur de rendu de cellules dessine la colonne pour une ligne donnée (sur la base, par exemple, du modèle de données sous-jacent de cette table).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X