6

の に複数追加JProgressBarしましTableColumnJTable

特定の計算を行った後、すべての JProgressBar をデータで更新していますが、最後に追加されたものProgressBar(この場合は ) のみが更新されています。ProgressBar progressObj4

ProgressBarすべてのsを更新するにはどうすればよいですか?

基本的な要件は、アップロード中にファイル進行状況バーのステータスを表示していることです。現在、4 つのプログレス バーをハードコーディングして、すべてのプログレス バーがファイルのステータスに基づいて更新されているかどうかをテストしていますが、それらを動的に作成する必要があります。プログレスバーの総数は、アップロードされているファイルの数を示しています。また、進行状況バーの個々のインスタンスを取得してステータスを更新するにはどうすればよいですか?

テーブル列に追加されるプログレスバーのソースコードを添付しています。

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

2 に答える 2

8

基本的にSwingWorkerと Runnable#ThreadJProgressBarを使用して移動する方法は 2 つあります。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;
    }
}
于 2011-08-12T06:09:36.660 に答える
3

私の知る限り、レンダラーは特定の列のすべての行に適用されます。同じ列に複数のレンダラーを適用したいようです。さらに、セルレンダラーに状態を与えようとしているようです。

レンダラーをステートレスにし、レンダラーのメソッド getTableCellRendererComponent() が、レンダラーがセルを描画する前に、現在の行の値に基づいてさまざまな (JProgressBar) プロパティを設定するようにすると役立つと思います。

つまり、特定の列に対して tc.setCellRenderer() を 1 回呼び出すだけでよく、セル レンダラーで特定の行の列を (たとえば、そのテーブルの基礎となるデータ モデルに基づいて) 描画する必要があります。

于 2011-08-12T06:07:03.043 に答える