JTable的TableColumn添加多个JProgressBar
Posted
技术标签:
【中文标题】JTable的TableColumn添加多个JProgressBar【英文标题】:Adding multiple JProgressBar to TableColumn of JTable 【发布时间】:2011-10-25 13:09:51 【问题描述】:我已将多个JProgressBar
添加到TableColumn
中的JTable
。
在进行某些计算后,我正在使用数据更新所有 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);
【问题讨论】:
【参考方案1】:据我所知,渲染器适用于给定列中的所有行。在我看来,您想将多个渲染器应用于同一列。此外,您似乎还试图赋予单元格渲染器状态。
我相信这将有助于使渲染器无状态,并让渲染器的方法 getTableCellRendererComponent() 在渲染器绘制单元格之前根据当前行的值设置各种 (JProgressBar) 属性。
换句话说,您应该只需要为任何给定列调用一次 tc.setCellRenderer(),然后让您的单元格渲染器为任何给定行绘制列(例如,基于该行的基础数据模型)表)。
【讨论】:
【参考方案2】:基本上有两种方式移动JProgressBar
,使用SwingWorker和Runnable#Thread,例如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;
【讨论】:
+1 用于错误测试!参照。这个相关的example。以上是关于JTable的TableColumn添加多个JProgressBar的主要内容,如果未能解决你的问题,请参考以下文章
TableColumn setPreferredWidth不起作用
如何在JTable Invisible for Swing Java中创建一个列
向 Tableview Javafx 动态添加和删除 tablecolumn
Java Swing 如何使用DefaultTableModel交替刷新JTable?