在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>
 * 
 * 
@author chenpeng
 * @email:[email protected]
 * 
@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:[email protected]
 * 
@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);

    }

}


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

你可能感兴趣的:(jtable)