2011-08-12 6 views
6

TableColumnJTableに複数追加しました。JTableのTableColumnに複数のJProgressBarを追加する

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

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

基本的な要件は、アップロード中に進行状況バーにファイルのステータスを表示することです。現在、すべてのプログレスバーがファイルのステータスを更新しているかどうかをテストするために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); 

答えて

8

基本的に2つの方法があるが、SwingWorkerとのRunnable#スレッドを使用してJProgressBarでエラー検査のため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; 
    } 
} 
+0

+1のための一例を動かします! Cf。この関連する[例](http://stackoverflow.com/questions/3483485/java-jprogressbar-or-equivalent-in-a-jtabbedpane-tab-title/3484251#3484251)。 – trashgod

3

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

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

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

関連する問題