2

我正在使用以下代码,该代码在 AbstractTableModel 中包含一个 JProgressBar。JProgressBar 进度值在 getValueAt() 函数的“案例 5:”中通过返回 Float 进行更新。我想弄清楚的是如何访问底层的 JProgressBar 实例,以便我可以修改它的一些属性而不是进度值(例如 setVisible())。

package org.jdamico.jhu.runtime;

import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

// This class manages the upload table's data.
class TransfersTableModel extends AbstractTableModel implements Observer {

    /**
     * 
     */
    private static final long serialVersionUID = 2740117506937325535L;

    // These are the names for the table's columns.
    private static final String[] columnNames = { "Type","Name", "UUID","Status",
            "Stage","Progress","Total Start Time","Total End Time" };

    // These are the classes for each column's values.
    private static final Class[] columnClasses = { String.class,String.class,String.class, 
            String.class,String.class, JProgressBar.class, String.class, String.class};

    // The table's list of uploads.
    private ArrayList<ParentEntry> transferList = new ArrayList<ParentEntry>();

    // Add a new upload to the table.
    public void addTransfer(ParentEntry pe) {

        // Register to be notified when the upload changes.
        pe.addObserver(this);

        transferList.add(pe);

        // Fire table row insertion notification to table.
        fireTableRowsInserted(getRowCount(), getRowCount());
    }

    // Get a upload for the specified row.
    public ParentEntry getTransfer(int row) {
        return transferList.get(row);
    }

    // Remove a upload from the list.
    public void clearTransfer(int row) {
        transferList.remove(row);

        // Fire table row deletion notification to table.
        fireTableRowsDeleted(row, row);
    }

    // Get table's column count.
    public int getColumnCount() {
        return columnNames.length;
    }

    // Get a column's name.
    public String getColumnName(int col) {
        return columnNames[col];
    }

    // Get a column's class.
    public Class getColumnClass(int col) {
        return columnClasses[col];
    }

    // Get table's row count.
    public int getRowCount() {
        return transferList.size();
    }

    // Get value for a specific row and column combination.
    public Object getValueAt(int row, int col) {

        ParentEntry pe = transferList.get(row);
        switch (col) {
        case 0:
            return pe.getType();
        case 1: // URL
            return pe.getUrl();
        case 2: //UUID
            return pe.getUUID() + "";
        case 3: // Status
            return pe.getStatus().getDisplay();
        case 4: // Stage
            return pe.getStage().getDisplay();
        case 5: //Progress
            return new Float(pe.getProgress());
        case 6:
            if (pe.getTotalStartTime() != null)
                return pe.getTotalStartTime().getTime().toString();
            else
                return "";
        case 7:
            if (pe.getTotalEndTime() != null)
                return pe.getTotalEndTime().getTime().toString();
            else
                return "";
        }
        return "";
    }

    /*
     * Update is called when a Upload notifies its observers of any changes
     */
    public void update(Observable o, Object arg) {
        int index = transferList.indexOf(o);

        // Fire table row update notification to table.
        fireTableRowsUpdated(index, index);
    }
}

更新:这原本不是我的代码,我还在熟悉它,但我刚刚发现有一个 ProgressRenderer 类,它扩展了 JProgressBar 并实现了 TableCellRenderer。这是用于在表格中呈现进度条的内容。因此,我将更改此代码以更改进度条的显示方式:

package org.jdamico.jhu.runtime;

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

/*import org.jdamico.jhu.components.Controller;
import org.jdamico.jhu.components.FilePartition;
import org.vikulin.utils.Constants;*/

// This class renders a JProgressBar in a table cell.
class ProgressRenderer extends JProgressBar implements TableCellRenderer {




    // Constructor for ProgressRenderer.
    public ProgressRenderer(int min, int max) {
        super(min, max);
    }

    /*
     * Returns this JProgressBar as the renderer for the given table cell.
     */
    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
        // Set JProgressBar's percent complete value.
        Float tmp = ((Float) value).floatValue();
        if (tmp == -1) {
            this.setVisible(false);
        }
        else {
            setValue((int) ((Float) value).floatValue());
            if (this.isVisible() == false)
                this.setVisible(true);
        }
        return this;
    }



}
4

2 回答 2

3

您可以向该类添加一个方法,该方法允许您获取与感兴趣的行关联的 JProgressBar,例如:

   public JProgressBar getProgressBar(int row) {
      ParentEntry pe = transferList.get(row);
      return pe.getProgress();
   }

对我来说,模型将包含一个 JProgressBar 而不是一个表示完成百分比的简单 int 对我来说似乎有点有趣。将进度条显示的任何代码放在 JTable 的单元格渲染器中对我来说更有意义。

编辑 1
回复以下 opike 的评论:

在模型外部使用 JProgressBar 是否真的让代码比在模型内部更有效?收益是否足以花时间重写代码?现有代码在大多数情况下都按照我需要的方式工作,所以我宁愿只调整它而不是更重要的重写。

我的问题和我担心的是,您的单元格渲染器是否使用模型持有的 JProgressBar?如果是这样,如果它没有办法获得JProgressBar怎么办?如果它只使用获得的 Float 值,那么模型保存未使用的信息和资源是没有意义的。是的,这可能会显着减慢您的程序。

于 2011-06-12T02:18:32.687 回答
3

为什么使用 AbstractTableModel,也不在这个代码块中添加 JTable 值,真的不需要,例如 DefalultTableModel 可以做到这一点

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;

public class ProgressBarTableCellRendererExample {

    private Random random = new Random();
    private JTable table;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ProgressBarTableCellRendererExample().makeUI();
            }
        });
    }

    public void makeUI() {
        table = new JTable(11, 1) {

            private Object[][] data;
            private static final long serialVersionUID = 1L;

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }

            @Override
            public Class<?> getColumnClass(int column) {
                return Integer.class;
            }
        };
        randomize();
        table.setDefaultRenderer(Integer.class, new ProgressBarTableCellRenderer());
        table.setRowHeight(20);
        table.setRowMargin(2);
        JButton button = new JButton("Randomize");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                randomize();
                getTableValue();
            }
        });
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(table), BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(150, 150);
        frame.setPreferredSize(new Dimension(600, 300));
        frame.pack();
        frame.setVisible(true);
    }

    private void randomize() {
        for (int i = 0; i < table.getRowCount(); i++) {
            table.setValueAt(random.nextInt(100), i, 0);
        }
    }

    private void getTableValue() {
        for (int i = 0; i < table.getRowCount(); i++) {
            System.out.println(String.valueOf(table.getValueAt(i, 0)));
        }
    }

    private class ProgressBarTableCellRenderer extends JProgressBar implements TableCellRenderer {

        private static final long serialVersionUID = 1L;

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                boolean hasFocus, int row, int column) {
            setValue((Integer) value);
            System.out.println("Tables Row: " + row + ", Column : " + column + ", has value - " + value);
            return this;
        }
    }
}
于 2011-06-12T05:59:17.193 回答