我們?cè)诙辔募螺d或多事務(wù)處理時(shí),經(jīng)常會(huì)出現(xiàn)使用線程以提高效率的情況,而這時(shí)在GUI程序中如何表示進(jìn)度,就成了一個(gè)不大不小的問題。
現(xiàn)在比較被大眾接受的方式,大體就是如迅雷等下載工具中一樣,用表格中加載進(jìn)度條以進(jìn)行顯示。
而對(duì)于Swing來說,并沒有現(xiàn)成的組件能夠?qū)崿F(xiàn)這一操作,還有下載的并發(fā),似乎也需要額外進(jìn)行處理。于是,我在此提供一個(gè)基于jdk1.6版本的示例,以供參考。(因?yàn)閖dk1.6提供了SwingWorker,簡化了圖形程序中的線程處理,使用其他jdk開發(fā)請(qǐng)?zhí)鎿Q此項(xiàng)即可)
本示例由兩個(gè)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(
"
進(jìn)度
"
,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);
//
背景色及字體設(shè)置
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(
"
進(jìn)度條測(cè)試
"
,
100
),
null
);
//
滾動(dòng)條
JScrollPanescrollPane
=
new
JScrollPane(table);
//
背景色
scrollPane.getViewport().setBackground(Color.black);
//
彈出菜單
table.setComponentPopupMenu(
new
JPopupMenu());
//
是否始終大到足以填充封閉視口的高度
table.setFillsViewportHeight(
true
);
//
將單元格間距的高度和寬度設(shè)置為指定的Dimension
table.setIntercellSpacing(
new
Dimension());
//
是否繪制單元格間的水平線
table.setShowHorizontalLines(
true
);
//
是否繪制單元格間的垂直線
table.setShowVerticalLines(
false
);
//
停止編輯時(shí)重新定義焦點(diǎn),避免TableCellEditor丟失數(shù)據(jù)
table.putClientProperty(
"
terminateEditOnFocusLost
"
,Boolean.TRUE);
//
表示JTable中列的所有屬性,如寬度、大小可調(diào)整性、最小和最大寬度等。
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);
}
}
/**
*創(chuàng)建事件
*
@param
evt
*/
private
void
createNewActionPerformed(ActionEventevt)
{
final
int
key
=
model.getRowCount();
//
在jdk1.6后,當(dāng)一個(gè)Swing程序需要執(zhí)行一個(gè)多線程任務(wù)時(shí),可以通過javax.swing.SwingWorker實(shí)例進(jìn)行實(shí)現(xiàn)。
//
SwingWorker的process可以定義約束屬性。更改這些屬性將觸發(fā)事件,并從事件調(diào)度線程上引起事件處理方法的調(diào)用。
//
SwingWorker的done方法,在后臺(tái)任務(wù)完成時(shí)自動(dòng)的在事件調(diào)度線程上被調(diào)用。
SwingWorker
<
Integer,Integer
>
worker
=
new
SwingWorker
<
Integer,Integer
>
()
{
//
隨機(jī)sleep
private
int
sleepDummy
=
new
Random().nextInt(
100
)
+
1
;
//
最大任務(wù)數(shù)量
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;
}
/**
*進(jìn)行中處理
*/
protected
void
process(java.util.List
<
Integer
>
data)
{
for
(Integervalue:data)
{
//
把數(shù)據(jù)填入對(duì)應(yīng)的行列
model.setValueAt(value,key,
2
);
}
//
傳送變更事件給指定行列
model.fireTableCellUpdated(key,
2
);
}
/**
*完成后處理
*/
protected
void
done()
{
}
}
;
model.addTest(
new
Test(
"
進(jìn)度條測(cè)試
"
,
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);
}
}
/**
*取消進(jìn)度
*
@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();
}
/**
*取消下載進(jìn)程
*
*
@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中加載進(jìn)度條及進(jìn)行操作
"
);
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
);
}
}
運(yùn)行效果如下:
現(xiàn)在比較被大眾接受的方式,大體就是如迅雷等下載工具中一樣,用表格中加載進(jìn)度條以進(jìn)行顯示。
而對(duì)于Swing來說,并沒有現(xiàn)成的組件能夠?qū)崿F(xiàn)這一操作,還有下載的并發(fā),似乎也需要額外進(jìn)行處理。于是,我在此提供一個(gè)基于jdk1.6版本的示例,以供參考。(因?yàn)閖dk1.6提供了SwingWorker,簡化了圖形程序中的線程處理,使用其他jdk開發(fā)請(qǐng)?zhí)鎿Q此項(xiàng)即可)
本示例由兩個(gè)java文件組成
MyTableModel.java

























































































































































MyPanel.java





























































































































































































































































































































運(yùn)行效果如下:

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
