有人能告诉我刷新JTable的最佳方法吗?我试图从另一个线程使用table.repaint()
,但我不知道这是否是最佳方式。
我的代码:
类:模型
public class CLS_ValueUpdater extends Thread {
private String sRowName;
private String sValue;
public CLS_ValueUpdater(String sRowName) {
this.sRowName = sRowName;
this.start();
}
public String getValue() {
return this.sValue;
}
public String getRowName() {
return sRowName;
}
public void setRowName(String sRowName) {
this.sRowName = sRowName;
}
public void run() {
try {
for (int i = 0; i <= 100; i++) {
this.sValue = String.valueOf(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
类:控制器
public class CLS_Controller extends AbstractTableModel {
private static final long serialVersionUID = -5603593230985106202L;
private String[] sArrColumns = { "Nombre", "Valor" };
private ArrayList<CLS_ValueUpdater> tListUpdater = new ArrayList<CLS_ValueUpdater>();
public CLS_Controller() {
super();
}
public void addRow(String sName) {
this.tListUpdater.add(new CLS_ValueUpdater(sName));
this.fireTableDataChanged();
}
public void deleteRow(int iIndex) {
this.tListUpdater.remove(iIndex);
this.fireTableDataChanged();
}
@Override
public String getColumnName(int iColumn) {
return this.sArrColumns[iColumn];
}
@Override
public int getColumnCount() {
return this.sArrColumns.length;
}
@Override
public int getRowCount() {
return this.tListUpdater.size();
}
@Override
public Object getValueAt(int iRow, int iColumn) {
CLS_ValueUpdater tValueUpdater = this.tListUpdater.get(iRow);
switch (iColumn) {
case 0:
return tValueUpdater.getRowName();
case 1:
return tValueUpdater.getValue();
default:
return null;
}
}
@Override
public void setValueAt(Object oValue, int iRow, int iColumn) {
CLS_ValueUpdater tValueUpdater = this.tListUpdater.get(iRow);
switch (iColumn) {
case 0:
tValueUpdater.setRowName(oValue.toString());
break;
}
this.fireTableCellUpdated(iRow, iColumn);
}
@Override
public Class<String> getColumnClass(int iColumn) {
return String.class;
}
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
}
分类:查看
public class FRM_Main {
private JFrame frame;
private JTable table;
private CLS_Controller tModel = new CLS_Controller();
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FRM_Main window = new FRM_Main();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public FRM_Main() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 476, 283);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane();
JButton btnNewButton = new JButton("Add");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
tModel.addRow(textField.getText());
}
});
JButton btnNewButton_1 = new JButton("Delete");
textField = new JTextField();
textField.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(gl_panel
.createParallelGroup(Alignment.LEADING)
.addGroup(
gl_panel.createSequentialGroup()
.addContainerGap()
.addGroup(
gl_panel.createParallelGroup(
Alignment.LEADING)
.addComponent(
scrollPane,
GroupLayout.DEFAULT_SIZE,
440, Short.MAX_VALUE)
.addGroup(
Alignment.TRAILING,
gl_panel.createSequentialGroup()
.addComponent(
textField,
GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
ComponentPlacement.RELATED)
.addComponent(
btnNewButton)
.addPreferredGap(
ComponentPlacement.RELATED,
216,
Short.MAX_VALUE)
.addComponent(
btnNewButton_1)))
.addContainerGap()));
gl_panel.setVerticalGroup(gl_panel
.createParallelGroup(Alignment.LEADING)
.addGroup(
gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(scrollPane,
GroupLayout.PREFERRED_SIZE, 194,
GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(
gl_panel.createParallelGroup(
Alignment.BASELINE)
.addComponent(btnNewButton_1)
.addComponent(
textField,
GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
.addComponent(btnNewButton))
.addContainerGap(80, Short.MAX_VALUE)));
table = new JTable();
table.setShowVerticalLines(false);
table.setShowHorizontalLines(false);
table.setFillsViewportHeight(true);
table.setModel(tModel);
new tableUpdater(table);
scrollPane.setViewportView(table);
panel.setLayout(gl_panel);
}
}
class tableUpdater extends Thread {
private JTable tTable;
public tableUpdater(JTable tTable) {
this.tTable = tTable;
this.start();
}
public void run() {
try {
while (true) {
tTable.repaint();
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
那么有没有优雅的方式来自动转换JTable?提前谢谢!
答案 0 :(得分:2)
我试图从另一个线程
使用table.repaint()
如果另一个帖子不是EDT,那么你的桌子就不会被重新粉刷。
您想要使用进度条更新您的jtable。您可能对使用SwingWorker
感兴趣。这是一个完整的example。
class MySwingWorker extends SwingWorker <String,String>{ //what params you want here
@Override
protected String doInBackground()throws Exception{
//here you download heavy task
//and you call publish() when you want
}
@Override
protected void process(List<String> chunks){
// here you updated your gui
//setValueAt(row,col); and fireTableCellUpdated(row,col);
}
@Override
protected void done(){
//here is called when doInBackGround is finished
}
}
因此,您必须使用swingWorker为您提供的部分结果来调用setValue(int row, int column)
和fireTableCellUpdated(int row,int col);
。
BTW当你插入一行
public void addRow(String sName) {
this.tListUpdater.add(new CLS_ValueUpdater(sName));
this.fireTableDataChanged();
}
可能更好地致电
void fireTableRowsInserted(int firstRow, int lastRow)
答案 1 :(得分:0)
DefaultTableModel#setValueAt ()
的javadoc说:
在列和行设置单元格的对象值。 aValue是 新的价值。此方法将生成tableChanged通知。
因此,如果您通过调用model.setValueAt()
来更改内容,那么也会触发重新绘制。
注意:model
是TableModel
的{{1}}。
答案 2 :(得分:-1)
如果要每1秒刷新一次表,请使用单独的线程进行刷新;不要忘记使用invokeLater方法。
new Thread(new Runnable(){
public void run()
{
while(true)
{
Thread.sleep(1000);
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
_tableModel.fireTableDataChanged();
}
});
}
}
}).start();