技术开发 频道

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

  【IT168 技术文档】我们在多文件下载或多事务处理时,经常会出现使用线程以提高效率的情况,而这时在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;   /*   * @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(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(0, 100);   public ProgressRenderer() {   super();   setOpaque(true);   b.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));   }   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;   / *   * @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(250, 250, 250);   private final MyTableModel model = new MyTableModel();   private final TableRowSorter sorter = new TableRowSorter(   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(320, 180));   }   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 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 set = new HashSet();   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(400, 400);   // 透明度90%   // NativeLoader.getInstance().setTransparence(frame, 0.9f);   // 居中   frame.setLocationRelativeTo(null);   frame.setVisible(true);   }   }
0
相关文章