我在JTable中实现了一个JProgressBar。 我使用渲染器作为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;
}
}
答案 0 :(得分:3)
看起来您正在尝试将ProgressBar用作CellRenderer。你应该知道的一件事是,CellRenders在绘制单元格时仅 被调用,而在其他时刻设置值无效:这是因为Swing对渲染器使用了flyweight模式,因此重用渲染器。
为了获得你想要的效果,你应该
getTableCellRendererComponent
返回之前设置所需的所有值,因此,请删除invokeLater
(在EDT上调用getter,因此您无需担心关于穿线那里)。答案 1 :(得分:2)
1)甚至可以,不要在JComponents
内创建TableCellRenderer
,也不要在re_create对象中创建,渲染器仅用于格式化单元格内容
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();
}
}
答案 2 :(得分:1)
看看Swing table tutorial: renderers and editors。渲染器使用该组件进行某种“标记”。之后更改组件无效,因为组件实际上不包含在UI中。这是您可以一遍又一遍地返回相同组件的原因之一,如果组件实际包含在表中,则无法实现。这些都在链接教程中进行了解释。
要解决您的问题,只需删除SwingUtilities.invokeLater
方法调用,然后返回JProgressBar
,其中设置了正确的进度。
如果我看到的正确,您的TableModel
包含JProgressBar
。我希望有一个很好的理由,因为这是一个UI组件,通常不应该包含在模型方面。这是基于您的
final JProgressBar bar = (JProgressBar) value;
在渲染器中调用。我强烈建议您查看一下TableModel
,看看是否可以避免这种情况