JProgressBar setValue 不起作用,也尝试使用 SwingUtilities
Posted
技术标签:
【中文标题】JProgressBar setValue 不起作用,也尝试使用 SwingUtilities【英文标题】:JProgressBar setValue is not working, tried with SwingUtilities as well 【发布时间】:2012-03-06 14:48:45 【问题描述】:我在 JTable 中实现了 JProgressBar。 我使用 renderer 作为 ProgressBar NOT EDITOR。
现在我尝试实现一个 ProgressBar 设置值,但由于 EDT 无法正常工作,因此我使用了 SwingUtilties,但效果不佳。
预期行为 - JProgressBar 必须将值设置为 80 , 目前只显示0%
public class SkillSetTableProgressBarRenderer extends JProgressBar implements
TableCellRenderer
public SkillSetTableProgressBarRenderer()
super(0, 100);
super.setPreferredSize(new Dimension(100, 80));
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
final JProgressBar bar = (JProgressBar) value;
if (bar.getString().equals("JAVA") || bar.getString().equals("SWING"))
super.setString("Mellow");
else
super.setString("GOOD");
setOpaque(true);
table.setOpaque(true);
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
System.err.println("MAIN ANDER");
setValue(80);
bar.setValue(80);
);
super.setStringPainted(true);
super.setIndeterminate(true);
super.setPreferredSize(new Dimension(140, 16));
if (isSelected)
super.setBackground(table.getSelectionBackground());
super.setForeground(table.getSelectionForeground());
// this.setBackground(table.getSelectionBackground());
else
super.setForeground(table.getForeground());
super.setBackground(Color.WHITE);
return this;
【问题讨论】:
请定义“不工作”、您的预期行为、异常等。 不确定这是否与此线程相似,但仅供参考:***.com/questions/9288923/how-to-update-jprogress-bar 【参考方案1】:看起来您正在尝试将 ProgressBar 用作 CellRenderer。您应该知道的一件事是,CellRenders 仅在绘制单元格时调用,而在其他时刻设置值无效:这是因为 Swing 使用享元模式进行渲染,因此重用渲染器。
要达到你想要的效果,你应该
通知表格单元格将被更新,例如通过更新其底层模型(这将触发必要的事件),并且 在getTableCellRendererComponent
返回之前设置您需要的所有值,因此,删除invokeLater
(在 EDT 上调用 getter,因此您无需担心那里的线程) .
【讨论】:
【参考方案2】:看看Swing table tutorial: renderers and editors。渲染器使用该组件制作一种“印章”。之后更改组件无效,因为该组件实际上并未包含在您的 UI 中。这就是您可以一遍又一遍地返回相同组件的原因之一,如果该组件实际上包含在表中,这是不可能的。这在链接的教程中都有解释。
要解决您的问题,只需删除SwingUtilities.invokeLater
方法调用,并返回设置正确进度的JProgressBar
。
如果我没看错的话,你有一个 TableModel
包含一个 JProgressBar
。我希望这是有充分理由的,因为这是一个 UI 组件,通常不应包含在模型端。这是基于您的
final JProgressBar bar = (JProgressBar) value;
在渲染器中调用。我强烈建议您查看您的TableModel
,看看是否可以避免这种情况
【讨论】:
【参考方案3】:1) 甚至是可以的,不要在TableCellRenderer
里面创建JComponents
,也不要re_create Object,Renderer只是用来格式化单元格内容
2) 使用SwingWorker
在JProgressBar
中移动(如果您有真正重要的原因,请使用Runnable#Tread
)
关于Runnable#Tread
的例子
import java.awt.Component;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class TableWithProgressBars
public static class ProgressRenderer extends JProgressBar implements TableCellRenderer
private static final long serialVersionUID = 1L;
public ProgressRenderer(int min, int max)
super(min, max);
this.setStringPainted(true);
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column)
this.setValue((Integer) value);
return this;
private static final int maximum = 100;
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
new TableWithProgressBars().createGUI();
);
public void createGUI()
final JFrame frame = new JFrame("Progressing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Integer[] oneRow = 0, 0, 0, 0;
String[] headers = "One", "Two", "Three", "Four";
Integer[][] data = oneRow, oneRow, oneRow, oneRow, oneRow,;
final DefaultTableModel model = new DefaultTableModel(data, headers);
final JTable table = new JTable(model);
table.setDefaultRenderer(Object.class, new ProgressRenderer(0, maximum));
table.setPreferredScrollableViewportSize(table.getPreferredSize());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
new Thread(new Runnable()
@Override
public void run()
Object waiter = new Object();
synchronized (waiter)
int rows = model.getRowCount();
int columns = model.getColumnCount();
Random random = new Random(System.currentTimeMillis());
boolean done = false;
while (!done)
int row = random.nextInt(rows);
int column = random.nextInt(columns);
Integer value = (Integer) model.getValueAt(row, column);
value++;
if (value <= maximum)
model.setValueAt(value, row, column);
try
waiter.wait(15);
catch (InterruptedException e)
e.printStackTrace();
done = true;
for (row = 0; row < rows; row++)
for (column = 0; column < columns; column++)
if (!model.getValueAt(row, column).equals(maximum))
done = false;
break;
if (!done)
break;
frame.setTitle("All work done");
).start();
【讨论】:
以上是关于JProgressBar setValue 不起作用,也尝试使用 SwingUtilities的主要内容,如果未能解决你的问题,请参考以下文章
Java - 如何将 JProgressBar 与 SwingWorker 一起使用
使用dwr后,javaweb设置的session超时失效,web.xml和tomcat设置都不起作
具有 NSObject 继承的泛型类,self.setValue(, forKey:) 不起作用