在JTable中加载进度条及进行操作

系统 1648 0
我们在多文件下载或多事务处理时,经常会出现使用线程以提高效率的情况,而这时在GUI程序中如何表示进度,就成了一个不大不小的问题。
现在比较被大众接受的方式,大体就是如迅雷等下载工具中一样,用表格中加载进度条以进行显示。
而对于Swing来说,并没有现成的组件能够实现这一操作,还有下载的并发,似乎也需要额外进行处理。于是,我在此提供一个基于jdk1.6版本的示例,以供参考。(因为jdk1.6提供了SwingWorker,简化了图形程序中的线程处理,使用其他jdk开发请替换此项即可)

本示例由两个java文件组成

MyTableModel.java
package org.loon.test;

import java.awt.Component;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JProgressBar;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

public class MyTableModel extends DefaultTableModel ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

private static final ColumnContext[]columnArray = ... {
new ColumnContext( " ID " ,Integer. class , false ),
new ColumnContext( " 名称 " ,String. class , false ),
new ColumnContext( " 进度 " ,Integer. class , false )}
;

private final Map < Integer,SwingWorker > swmap = new HashMap < Integer,SwingWorker > ();

private int number = 0 ;

public void addTest(Testt,SwingWorkerworker) ... {
Object[]obj
= ... { new Integer(number),t.getName(),t.getProgress()} ;
super .addRow(obj);
swmap.put(number,worker);
number
++ ;
}


public synchronized SwingWorkergetSwingWorker( int identifier) ... {
Integerkey
= (Integer)getValueAt(identifier, 0 );
return swmap.get(key);
}


public TestgetTest( int identifier) ... {
return new Test((String)getValueAt(identifier, 1 ),
(Integer)getValueAt(identifier,
2 ));
}


public boolean isCellEditable( int row, int col) ... {
return columnArray[col].isEditable;
}



public Class <?> getColumnClass( int modelIndex) ... {
return columnArray[modelIndex].columnClass;
}


public int getColumnCount() ... {
return columnArray.length;
}


public StringgetColumnName( int modelIndex) ... {
return columnArray[modelIndex].columnName;
}


private static class ColumnContext ... {
public final StringcolumnName;

public final ClasscolumnClass;

public final boolean isEditable;

public ColumnContext(StringcolumnName,ClasscolumnClass,
boolean isEditable) ... {
this .columnName = columnName;
this .columnClass = columnClass;
this .isEditable = isEditable;
}

}

}


class Test ... {
private Stringname;

private Integerprogress;

public Test(Stringname,Integerprogress) ... {
this .name = name;
this .progress = progress;
}


public void setName(Stringstr) ... {
name
= str;
}


public void setProgress(Integerstr) ... {
progress
= str;
}


public StringgetName() ... {
return name;
}


public IntegergetProgress() ... {
return progress;
}

}


class ProgressRenderer extends DefaultTableCellRenderer ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;
private final JProgressBarb = new JProgressBar( 0 , 100 );

public ProgressRenderer() ... {
super ();
setOpaque(
true );
b.setBorder(BorderFactory.createEmptyBorder(
1 , 1 , 1 , 1 ));
}


public ComponentgetTableCellRendererComponent(JTabletable,Objectvalue,
boolean isSelected, boolean hasFocus, int row, int column) ... {
Integeri
= (Integer)value;
Stringtext
= " 完成 " ;
if (i < 0 ) ... {
// 删除
text = " 取消完毕 " ;
}
else if (i < 100 ) ... {
b.setValue(i);
return b;
}

super .getTableCellRendererComponent(table,text,isSelected,hasFocus,
row,column);
return this ;
}

}


MyPanel.java
package org.loon.test;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.HashSet;
import java.util.Random;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableRowSorter;

// importorg.loon.framework.dll.NativeLoader;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

public class MyPanel extends JPanel ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

private static final ColorevenColor = new Color( 250 , 250 , 250 );

private final MyTableModelmodel = new MyTableModel();

private final TableRowSorter < MyTableModel > sorter = new TableRowSorter < MyTableModel > (
model);

private final JTabletable;

public MyPanel() ... {
super ( new BorderLayout());
table
= new JTable(model) ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

public ComponentprepareRenderer(
TableCellRenderertableCellRenderer,
int row, int column) ... {
Componentcomponent
= super .prepareRenderer(tableCellRenderer,row,
column);
// 背景色及字体设置
if (isRowSelected(row)) ... {
component.setForeground(getSelectionForeground());
component.setBackground(getSelectionBackground());
}
else ... {
component.setForeground(getForeground());
component.setBackground((row
% 2 == 0 ) ? evenColor:table
.getBackground());
}

return component;
}


public JPopupMenugetComponentPopupMenu() ... {
return makePopup();
}

}
;
table.setRowSorter(sorter);
model.addTest(
new Test( " 进度条测试 " , 100 ), null );

// 滚动条
JScrollPanescrollPane = new JScrollPane(table);
// 背景色
scrollPane.getViewport().setBackground(Color.black);
// 弹出菜单
table.setComponentPopupMenu( new JPopupMenu());
// 是否始终大到足以填充封闭视口的高度
table.setFillsViewportHeight( true );
// 将单元格间距的高度和宽度设置为指定的Dimension
table.setIntercellSpacing( new Dimension());
// 是否绘制单元格间的水平线
table.setShowHorizontalLines( true );
// 是否绘制单元格间的垂直线
table.setShowVerticalLines( false );
// 停止编辑时重新定义焦点,避免TableCellEditor丢失数据
table.putClientProperty( " terminateEditOnFocusLost " ,Boolean.TRUE);
// 表示JTable中列的所有属性,如宽度、大小可调整性、最小和最大宽度等。
TableColumncolumn = table.getColumnModel().getColumn( 0 );
column.setMaxWidth(
60 );
column.setMinWidth(
60 );
column.setResizable(
false );
column
= table.getColumnModel().getColumn( 2 );
// 绘制此列各值的TableCellRenderer
column.setCellRenderer( new ProgressRenderer());

// 添加按钮
add( new JButton( new CreateNewAction( " 添加 " , null )),BorderLayout.SOUTH);
add(scrollPane,BorderLayout.CENTER);
setPreferredSize(
new Dimension( 320 , 180 ));
}


class CreateNewAction extends AbstractAction ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

public CreateNewAction(Stringlabel,Iconicon) ... {
super (label,icon);
}


public void actionPerformed(ActionEventevt) ... {
createNewActionPerformed(evt);
}

}


/***/ /**
*创建事件
*
@param evt
*/

private void createNewActionPerformed(ActionEventevt) ... {
final int key = model.getRowCount();
// 在jdk1.6后,当一个Swing程序需要执行一个多线程任务时,可以通过javax.swing.SwingWorker实例进行实现。
// SwingWorker的process可以定义约束属性。更改这些属性将触发事件,并从事件调度线程上引起事件处理方法的调用。
// SwingWorker的done方法,在后台任务完成时自动的在事件调度线程上被调用。
SwingWorker < Integer,Integer > worker = new SwingWorker < Integer,Integer > () ... {
// 随机sleep
private int sleepDummy = new Random().nextInt( 100 ) + 1 ;

// 最大任务数量
private int taskSize = 200 ;

protected IntegerdoInBackground() ... {
int current = 0 ;
while (current < taskSize && ! isCancelled()) ... {
current
++ ;
try ... {
Thread.sleep(sleepDummy);
}
catch (InterruptedExceptionie) ... {
publish(
- 1 );
break ;
}

publish(
100 * current / taskSize);
}

return sleepDummy * taskSize;
}


/***/ /**
*进行中处理
*/

protected void process(java.util.List < Integer > data) ... {
for (Integervalue:data) ... {
// 把数据填入对应的行列
model.setValueAt(value,key, 2 );
}

// 传送变更事件给指定行列
model.fireTableCellUpdated(key, 2 );
}


/***/ /**
*完成后处理
*/

protected void done() ... {
}

}
;
model.addTest(
new Test( " 进度条测试 " , 0 ),worker);
worker.execute();
}


class CancelAction extends AbstractAction ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

public CancelAction(Stringlabel,Iconicon) ... {
super (label,icon);
}


public void actionPerformed(ActionEventevt) ... {
cancelActionPerformed(evt);
}

}


/***/ /**
*取消进度
*
@param evt
*/

public synchronized void cancelActionPerformed(ActionEventevt) ... {
int []selection = table.getSelectedRows();
if (selection == null || selection.length <= 0 )
return ;
for ( int i = 0 ;i < selection.length;i ++ ) ... {
int midx = table.convertRowIndexToModel(selection[i]);
SwingWorkerworker
= model.getSwingWorker(midx);
if (worker != null && ! worker.isDone()) ... {
worker.cancel(
true );
}

worker
= null ;
}

table.repaint();
}


/***/ /**
*取消下载进程
*
*
@author chenpeng
*
*/

class DeleteAction extends AbstractAction ... {
/***/ /**
*
*/

private static final long serialVersionUID = 1L ;

public DeleteAction(Stringlabel,Iconicon) ... {
super (label,icon);
}


public void actionPerformed(ActionEventevt) ... {
deleteActionPerformed(evt);
}

}


private final HashSet < Integer > set = new HashSet < Integer > ();

public synchronized void deleteActionPerformed(ActionEventevt) ... {
int []selection = table.getSelectedRows();
if (selection == null || selection.length <= 0 )
return ;
for ( int i = 0 ;i < selection.length;i ++ ) ... {
int midx = table.convertRowIndexToModel(selection[i]);
set.add(midx);
SwingWorkerworker
= model.getSwingWorker(midx);
if (worker != null && ! worker.isDone()) ... {
worker.cancel(
true );
}

worker
= null ;
}

// JTable过滤器
final RowFilter < MyTableModel,Integer > filter = new RowFilter < MyTableModel,Integer > () ... {

public boolean include(
Entry
<? extends MyTableModel, ? extends Integer > entry) ... {
Integermidx
= entry.getIdentifier();
return ! set.contains(midx);
}

}
;
sorter.setRowFilter(filter);
table.repaint();
}


private JPopupMenumakePopup() ... {
JPopupMenupop
= new JPopupMenu();
Actionact
= new CreateNewAction( " 添加 " , null );
pop.add(act);
act
= new CancelAction( " 取消 " , null );
int []selection = table.getSelectedRows();
if (selection == null || selection.length <= 0 )
act.setEnabled(
false );
pop.add(act);
// 分割线
pop.add( new JSeparator());
act
= new DeleteAction( " 删除 " , null );
if (selection == null || selection.length <= 0 )
act.setEnabled(
false );
pop.add(act);
return pop;
}


public static void main(String[]args) ... {
EventQueue.invokeLater(
new Runnable() ... {
public void run() ... {
createGUI();
}

}
);
}


public static void createGUI() ... {

JFrameframe
= new JFrame( " 在JTable中加载进度条及进行操作 " );
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.getContentPane().add(
new MyPanel());
frame.setSize(
400 , 400 );
// 透明度90%
// NativeLoader.getInstance().setTransparence(frame,0.9f);
// 居中
frame.setLocationRelativeTo( null );
frame.setVisible(
true );

}

}


运行效果如下:
在JTable中加载进度条及进行操作

在JTable中加载进度条及进行操作


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论