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

我们在多文件下载或多事务处理时,经常会出现使用线程以提高效率的情况,而这时在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>
*
*
@authorchenpeng
*@email:ceponline@yahoo.com.cn
*
@version0.1
*/

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

privatestaticfinallongserialVersionUID=1L;

privatestaticfinalColumnContext[]columnArray=...{
newColumnContext("ID",Integer.class,false),
newColumnContext("名称",String.class,false),
newColumnContext("进度",Integer.class,false)}
;

privatefinalMap<Integer,SwingWorker>swmap=newHashMap<Integer,SwingWorker>();

privateintnumber=0;

publicvoidaddTest(Testt,SwingWorkerworker)...{
Object[]obj
=...{newInteger(number),t.getName(),t.getProgress()};
super.addRow(obj);
swmap.put(number,worker);
number
++;
}


publicsynchronizedSwingWorkergetSwingWorker(intidentifier)...{
Integerkey
=(Integer)getValueAt(identifier,0);
returnswmap.get(key);
}


publicTestgetTest(intidentifier)...{
returnnewTest((String)getValueAt(identifier,1),
(Integer)getValueAt(identifier,
2));
}


publicbooleanisCellEditable(introw,intcol)...{
returncolumnArray[col].isEditable;
}



publicClass<?>getColumnClass(intmodelIndex)...{
returncolumnArray[modelIndex].columnClass;
}


publicintgetColumnCount()...{
returncolumnArray.length;
}


publicStringgetColumnName(intmodelIndex)...{
returncolumnArray[modelIndex].columnName;
}


privatestaticclassColumnContext...{
publicfinalStringcolumnName;

publicfinalClasscolumnClass;

publicfinalbooleanisEditable;

publicColumnContext(StringcolumnName,ClasscolumnClass,
booleanisEditable)...{
this.columnName=columnName;
this.columnClass=columnClass;
this.isEditable=isEditable;
}

}

}


class Test ... {
privateStringname;

privateIntegerprogress;

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


publicvoidsetName(Stringstr)...{
name
=str;
}


publicvoidsetProgress(Integerstr)...{
progress
=str;
}


publicStringgetName()...{
returnname;
}


publicIntegergetProgress()...{
returnprogress;
}

}


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

privatestaticfinallongserialVersionUID=1L;
privatefinalJProgressBarb=newJProgressBar(0,100);

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


publicComponentgetTableCellRendererComponent(JTabletable,Objectvalue,
booleanisSelected,booleanhasFocus,introw,intcolumn)...{
Integeri
=(Integer)value;
Stringtext
="完成";
if(i<0)...{
//删除
text="取消完毕";
}
elseif(i<100)...{
b.setValue(i);
returnb;
}

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

}


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>
*
*
@authorchenpeng
*@email:ceponline@yahoo.com.cn
*
@version0.1
*/

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

privatestaticfinallongserialVersionUID=1L;

privatestaticfinalColorevenColor=newColor(250,250,250);

privatefinalMyTableModelmodel=newMyTableModel();

privatefinalTableRowSorter<MyTableModel>sorter=newTableRowSorter<MyTableModel>(
model);

privatefinalJTabletable;

publicMyPanel()...{
super(newBorderLayout());
table
=newJTable(model)...{
/***//**
*
*/

privatestaticfinallongserialVersionUID=1L;

publicComponentprepareRenderer(
TableCellRenderertableCellRenderer,
introw,intcolumn)...{
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());
}

returncomponent;
}


publicJPopupMenugetComponentPopupMenu()...{
returnmakePopup();
}

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

//滚动条
JScrollPanescrollPane=newJScrollPane(table);
//背景色
scrollPane.getViewport().setBackground(Color.black);
//弹出菜单
table.setComponentPopupMenu(newJPopupMenu());
//是否始终大到足以填充封闭视口的高度
table.setFillsViewportHeight(true);
//将单元格间距的高度和宽度设置为指定的Dimension
table.setIntercellSpacing(newDimension());
//是否绘制单元格间的水平线
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(newProgressRenderer());

//添加按钮
add(newJButton(newCreateNewAction("添加",null)),BorderLayout.SOUTH);
add(scrollPane,BorderLayout.CENTER);
setPreferredSize(
newDimension(320,180));
}


classCreateNewActionextendsAbstractAction...{
/***//**
*
*/

privatestaticfinallongserialVersionUID=1L;

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


publicvoidactionPerformed(ActionEventevt)...{
createNewActionPerformed(evt);
}

}


/***//**
*创建事件
*
@paramevt
*/

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

//最大任务数量
privateinttaskSize=200;

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

publish(
100*current/taskSize);
}

returnsleepDummy*taskSize;
}


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

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

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


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

protectedvoiddone()...{
}

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


classCancelActionextendsAbstractAction...{
/***//**
*
*/

privatestaticfinallongserialVersionUID=1L;

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


publicvoidactionPerformed(ActionEventevt)...{
cancelActionPerformed(evt);
}

}


/***//**
*取消进度
*
@paramevt
*/

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

worker
=null;
}

table.repaint();
}


/***//**
*取消下载进程
*
*
@authorchenpeng
*
*/

classDeleteActionextendsAbstractAction...{
/***//**
*
*/

privatestaticfinallongserialVersionUID=1L;

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


publicvoidactionPerformed(ActionEventevt)...{
deleteActionPerformed(evt);
}

}


privatefinalHashSet<Integer>set=newHashSet<Integer>();

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

worker
=null;
}

//JTable过滤器
finalRowFilter<MyTableModel,Integer>filter=newRowFilter<MyTableModel,Integer>()...{

publicbooleaninclude(
Entry
<?extendsMyTableModel,?extendsInteger>entry)...{
Integermidx
=entry.getIdentifier();
return!set.contains(midx);
}

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


privateJPopupMenumakePopup()...{
JPopupMenupop
=newJPopupMenu();
Actionact
=newCreateNewAction("添加",null);
pop.add(act);
act
=newCancelAction("取消",null);
int[]selection=table.getSelectedRows();
if(selection==null||selection.length<=0)
act.setEnabled(
false);
pop.add(act);
//分割线
pop.add(newJSeparator());
act
=newDeleteAction("删除",null);
if(selection==null||selection.length<=0)
act.setEnabled(
false);
pop.add(act);
returnpop;
}


publicstaticvoidmain(String[]args)...{
EventQueue.invokeLater(
newRunnable()...{
publicvoidrun()...{
createGUI();
}

}
);
}


publicstaticvoidcreateGUI()...{

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

}

}


运行效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值