博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在JTable中加载进度条及进行操作
阅读量:4130 次
发布时间:2019-05-25

本文共 10422 字,大约阅读时间需要 34 分钟。

我们在多文件下载或多事务处理时,经常会出现使用线程以提高效率的情况,而这时在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.classfalse),
            
new ColumnContext("名称", String.classfalse),
            
new ColumnContext("进度", Integer.classfalse) }
;
    
private final Map<Integer, SwingWorker> swmap = new HashMap<Integer, SwingWorker>();
    
private int number = 0;
    
public void addTest(Test t, SwingWorker worker) {
        Object[] obj 
= new Integer(number), t.getName(), t.getProgress() };
        
super.addRow(obj);
        swmap.put(number, worker);
        number
++;
    }
    
public synchronized SwingWorker getSwingWorker(int identifier) {
        Integer key 
= (Integer) getValueAt(identifier, 0);
        
return swmap.get(key);
    }
    
public Test getTest(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 String getColumnName(int modelIndex) {
        
return columnArray[modelIndex].columnName;
    }
    
private static class ColumnContext {
        
public final String columnName;
        
public final Class columnClass;
        
public final boolean isEditable;
        
public ColumnContext(String columnName, Class columnClass,
                
boolean isEditable) {
            
this.columnName = columnName;
            
this.columnClass = columnClass;
            
this.isEditable = isEditable;
        }
    }
}
class
 Test 
{
    
private String name;
    
private Integer progress;
    
public Test(String name, Integer progress) {
        
this.name = name;
        
this.progress = progress;
    }
    
public void setName(String str) {
        name 
= str;
    }
    
public void setProgress(Integer str) {
        progress 
= str;
    }
    
public String getName() {
        
return name;
    }
    
public Integer getProgress() {
        
return progress;
    }
}
class
 ProgressRenderer 
extends
 DefaultTableCellRenderer 
{
    
/**
     * 
     
*/
    
private static final long serialVersionUID = 1L;
    
private final JProgressBar b = new JProgressBar(0100);
    
public ProgressRenderer() {
        
super();
        setOpaque(
true);
        b.setBorder(BorderFactory.createEmptyBorder(
1111));
    }
    
public Component getTableCellRendererComponent(JTable table, Object value,
            
boolean isSelected, boolean hasFocus, int row, int column) {
        Integer i 
= (Integer) value;
        String text 
= "完成";
        
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;
//
import org.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 Color evenColor = new Color(250250250);
    
private final MyTableModel model = new MyTableModel();
    
private final TableRowSorter<MyTableModel> sorter = new TableRowSorter<MyTableModel>(
            model);
    
private final JTable table;
    
public MyPanel() {
        
super(new BorderLayout());
        table 
= new JTable(model) {
            
/**
             * 
             
*/
            
private static final long serialVersionUID = 1L;
            
public Component prepareRenderer(
                    TableCellRenderer tableCellRenderer, 
int row, int column) {
                Component component 
= 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 JPopupMenu getComponentPopupMenu() {
                
return makePopup();
            }
        }
;
        table.setRowSorter(sorter);
        model.addTest(
new Test("进度条测试"100), null);
        
// 滚动条
        JScrollPane scrollPane = 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中列的所有属性,如宽度、大小可调整性、最小和最大宽度等。
        TableColumn column = 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(320180));
    }
    
class CreateNewAction extends AbstractAction {
        
/**
         * 
         
*/
        
private static final long serialVersionUID = 1L;
        
public CreateNewAction(String label, Icon icon) {
            
super(label, icon);
        }
        
public void actionPerformed(ActionEvent evt) {
            createNewActionPerformed(evt);
        }
    }
    
/**
     * 创建事件
     * 
@param evt
     
*/
    
private void createNewActionPerformed(ActionEvent evt) {
        
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 Integer doInBackground() {
                
int current = 0;
                
while (current < taskSize && !isCancelled()) {
                    current
++;
                    
try {
                        Thread.sleep(sleepDummy);
                    }
 catch (InterruptedException ie) {
                        publish(
-1);
                        
break;
                    }
                    publish(
100 * current / taskSize);
                }
                
return sleepDummy * taskSize;
            }
            
/**
             * 进行中处理
             
*/
            
protected void process(java.util.List<Integer> data) {
                
for (Integer value : 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(String label, Icon icon) {
            
super(label, icon);
        }
        
public void actionPerformed(ActionEvent evt) {
            cancelActionPerformed(evt);
        }
    }
    
/**
     * 取消进度
     * 
@param evt
     
*/
    
public synchronized void cancelActionPerformed(ActionEvent evt) {
        
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]);
            SwingWorker worker 
= 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(String label, Icon icon) {
            
super(label, icon);
        }
        
public void actionPerformed(ActionEvent evt) {
            deleteActionPerformed(evt);
        }
    }
    
private final HashSet<Integer> set = new HashSet<Integer>();
    
public synchronized void deleteActionPerformed(ActionEvent evt) {
        
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);
            SwingWorker worker 
= 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) {
                Integer midx 
= entry.getIdentifier();
                
return !set.contains(midx);
            }
        }
;
        sorter.setRowFilter(filter);
        table.repaint();
    }
    
private JPopupMenu makePopup() {
        JPopupMenu pop 
= new JPopupMenu();
        Action act 
= 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() {
        JFrame frame 
= new JFrame("在JTable中加载进度条及进行操作");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.getContentPane().add(
new MyPanel());
        frame.setSize(
400400);
        
// 透明度90%
        
// NativeLoader.getInstance().setTransparence(frame, 0.9f);
        
// 居中
        frame.setLocationRelativeTo(null);
        frame.setVisible(
true);
    }
}

转载地址:http://lybvi.baihongyu.com/

你可能感兴趣的文章
还不会正则表达式?看这篇!
查看>>
100道+ JavaScript 面试题,助你查漏补缺
查看>>
JavaScript深入理解之闭包
查看>>
这才是学习Vite2的正确姿势!
查看>>
7 个适用于所有前端开发人员的很棒API,你需要了解一下
查看>>
25个构建Web项目的HTML建议,你需要了解一下!
查看>>
【web素材】02-10款大气的购物商城网站模板
查看>>
6种方式实现JavaScript数组扁平化(flat)方法的总结
查看>>
如何实现a===1 && a===2 && a===3返回true?
查看>>
49个在工作中常用且容易遗忘的CSS样式清单整理
查看>>
20种在学习编程的同时也可以在线赚钱的方法
查看>>
隐藏搜索框:CSS 动画正反向序列
查看>>
12 个JavaScript 特性技巧你可能从未使用过
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(上)
查看>>
【视频教程】Javascript ES6 教程27—ES6 构建一个Promise
查看>>
【5分钟代码练习】01—导航栏鼠标悬停效果的实现
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(中)
查看>>
8种ES6中扩展运算符的用法
查看>>
【视频教程】Javascript ES6 教程28—ES6 Promise 实例应用
查看>>
127个超级实用的JavaScript 代码片段,你千万要收藏好(下)
查看>>