2011-08-12 3 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

에는 기본적으로 두 가지 방법이 있습니다 오류 테스트를 위해 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

일에 대한 SwingWorker와의 Runnable # 스레드, 예를 사용하여 JProgressBar로 이동합니다! Cf. 이 관련 [예제] (http://stackoverflow.com/questions/3483485/java-jprogressbar-or-equivalent-in-a-jtabbedpane-tab-title/3484251#3484251). – trashgod

3

제 생각에 렌더러는 주어진 열의 모든 행에 적용됩니다. 같은 열에 여러 렌더러를 적용하고 싶습니다. 또한 셀 렌더러 상태를 지정하려고 시도하는 것 같습니다.

렌더러의 상태를 변경하지 않고 렌더러의 메소드 getTableCellRendererComponent()가 렌더러가 셀을 페인트하기 전에 현재 행의 값을 기반으로 다양한 (JProgressBar) 속성을 설정하도록하는 데 도움이된다고 생각합니다.

즉, 지정된 열에 대해 한 번 tc.setCellRenderer()을 호출 한 다음 셀 렌더러에서 특정 행에 대한 열을 그릴 필요가 있습니다 (예 : 기본 데이터 모델을 기반으로). 그 테이블).