TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
我们在多文件下载或多事务处理时,经常会出现使用线程以提高效率的情况,而这时在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);
- }
- }
-
-
-
-
-
复制代码 运行效果如下:

源码下载:http://file.javaxxz.com/2014/11/10/235702750.zip |
|