将多个JProgressBar添加到JTable的TableColumn

我在JTable TableColumn中添加了多个JProgressBar

在进行某些计算后,我正在使用数据更新所有JProgressBar,但只添加了最后一个ProgressBar (在本例中为ProgressBar progressObj4 )。

如何更新所有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); 

基本上有两种方法可以使用SwingWorker和Runnable#Thread与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 worker = new SwingWorker() { 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 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; } } 

据我所知,渲染器适用于给定列中的所有行。 在我看来,您想将几个渲染器应用于同一列。 此外,您似乎也试图给出单元格渲染器状态。

我相信它将有助于使渲染器无状态并使渲染器的方法getTableCellRendererComponent()在渲染器绘制单元格之前根据当前行的值设置各种(JProgressBar)属性。

换句话说,您应该只需要为任何给定的列调用tc.setCellRenderer()一次,然后让您的单元格渲染器为任何给定的行绘制列(例如,基于该表的基础数据模型)。