4

编辑

我尝试将表模型改回 DefaultTableModel,但在编译代码时出现异常,我不知道为什么!

这是我的表初始化:

jTable1.setModel(new Table1Model());
jTable1.setDefaultRenderer(Color.class,new ColorRenderer(true));
jTable1.getColumnModel().getColumn(5).setCellEditor(new ColorEditor());

我的课程扩展了模型:

class Table1Model extends DefaultTableModel {
    //private String[] columnNames = {"Station #",
    private Object[] columnNames = {"Station #",
                                    "Name",
                                    "avg Time",
                                    "Buffer",
                                    "Buffer Parts",
                                    "Color"};
    private Object[][] data = {
    {"1", "Station 1",
     new Integer(10), false, new Integer(0), Color.red},
    {"2", "Station 2",
     new Integer(10), false, new Integer(0), Color.blue},
    {"3", "Station 3",
     new Integer(10), false, new Integer(0), Color.green},
    {"4", "Station 4",
     new Integer(10), false, new Integer(0), Color.orange},
    {"5", "Station 5",
     new Integer(10), false, new Integer(0), Color.black}
    };


    @Override
    public int getColumnCount() {
        return columnNames.length;
    }

   @Override
    public int getRowCount() {
       //int length = data.length;
       //int datalength = Integer.parseInt(length);
       return data.length;
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col].toString();
    }

    @Override
    public Object getValueAt(int row, int col) {
        return data[row][col];
    }

    /*
     * JTable uses this method to determine the default renderer/
     * editor for each cell.  If we didn't implement this method,
     * then the last column would contain text ("true"/"false"),
     * rather than a check box.
     */
    @Override
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    /*
     * Don't need to implement this method unless your table's
     * editable.
     */
    @Override
    public boolean isCellEditable(int row, int col) {
        //Note that the data/cell address is constant,
        //no matter where the cell appears onscreen.
        if (col == 0) { return false; }
        else if (col == 4) { 
            boolean di = (Boolean) getValueAt(row,(col-1));
            if (!di) { return false; }
            else { return true; }
        }
        else { return true; }
    }

    /*
     * Don't need to implement this method unless your table's
     * data can change.
     */
    @Override
    public void setValueAt(Object value, int row, int col) {
        data[row][col] = value;
        fireTableCellUpdated(row, col);
    }

   /*public void removeRow(int row) {
        data.removeRow(row);
    }*/


    private void printDebugData() {
        int numRows = getRowCount();
        int numCols = getColumnCount();

        for (int i=0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j=0; j < numCols; j++) {
                System.out.print("  " + data[i][j]);
            }
            System.out.println();
        }
        System.out.println("--------------------------");
    }
}

这会产生以下错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at SimGui$Table1Model.getRowCount(SimGui.java:863)
at javax.swing.table.DefaultTableModel.setDataVector(DefaultTableModel.java:224)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:124)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:106)
at javax.swing.table.DefaultTableModel.<init>(DefaultTableModel.java:86)
at SimGui$Table1Model.<init>(SimGui.java:832)
at SimGui.initComponents(SimGui.java:265)
at SimGui.<init>(SimGui.java:34)
at SimGui$16.run(SimGui.java:789)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:701)
at java.awt.EventQueue.access$000(EventQueue.java:102)
at java.awt.EventQueue$3.run(EventQueue.java:662)
at java.awt.EventQueue$3.run(EventQueue.java:660)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:671)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)

你能帮我找出问题所在吗?另外,我可以将 ColorEditor 与 DefaultTableModel 一起使用吗?

4

1 回答 1

4

你有两个明显的选择:要么给你的类一个getVectorData()方法,要么给它另一个类似有用的方法,让你从模型中提取数据的核心。您可能不应该使用 AbstractTableModel 变量,而是使用您自己的自定义类型的变量,该变量扩展 AbstractTableModel 以允许您能够调用模型的自定义方法。

IE,

MyTableModel model = (MyTableModel)jTable1.getModel();
SomeCollection myKeyData = model.getMyKeyData();

另外,这个声明:

我最近创建了自己的类来扩展 AbstractTableModel 以便能够在 isCellEditable 和 setValueAt 上插入一些逻辑。

对我来说没有意义,因为您始终可以使用 DefaultTableModel 并简单地覆盖这两种方法。但是,如果您使用 DefaultTableModel,请不要让它像您尝试做的那样保存对象的 2D 数组。而是通过适当的构造函数或通过其addRow(...)方法将数据输入其内部数据。否则,您将失去 DefaultTableModel 提供的所有功能。

编辑
如果你想使用 DefaultTableModel 来利用它的方法,那么你不能为你的模型使用单独的数据“核心”(这里是你的 Object[][]),而是必须将你的数据加载到保存在里面的模型中DefaultTableModel 超类。这可以通过正确的超级构造函数或通过使用其addRow(...)方法添加数据行来完成。

例如,在这里我将您的数据加载到 DefaultTableModel 覆盖中:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.*;
import javax.swing.table.*;

public class TableModelTest extends JPanel {
   private static final Object[][] DATA = {
         { "1", "Station 1", new Integer(10), false, new Integer(0), Color.red },
         { "2", "Station 2", new Integer(10), false, new Integer(0), Color.blue },
         { "3", "Station 3", new Integer(10), false, new Integer(0),
               Color.green },
         { "4", "Station 4", new Integer(10), false, new Integer(0),
               Color.orange },
         { "5", "Station 5", new Integer(10), false, new Integer(0),
               Color.black } };
   private MyTableModel myTableModel = new MyTableModel(DATA);
   private JTable table = new JTable(myTableModel);

   public TableModelTest() {
      setLayout(new BorderLayout());
      add(new JScrollPane(table), BorderLayout.CENTER);

      table.getColumnModel().getColumn(5)
            .setCellRenderer(new ColorCellRenderer());
      table.getColumnModel().getColumn(5).setCellEditor(new ColorCellEditor());
   }

   private static void createAndShowGui() {
      TableModelTest mainPanel = new TableModelTest();

      JFrame frame = new JFrame("TableModelTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

class ColorCellEditor extends AbstractCellEditor implements TableCellEditor {

   Color currentColor;
   JButton button;
   JColorChooser colorChooser;
   JDialog dialog;
   protected static final String EDIT = "edit";

   public ColorCellEditor() {
      ActionListener actionListener = new MyActionListener();
      button = new JButton();
      button.setActionCommand(EDIT);
      button.addActionListener(actionListener);
      button.setBorderPainted(false);

      colorChooser = new JColorChooser();
      dialog = JColorChooser.createDialog(button, "Pick a Color", true,
            colorChooser, actionListener, null);
   }

   private class MyActionListener implements ActionListener {

      public void actionPerformed(ActionEvent e) {
         if (EDIT.equals(e.getActionCommand())) {
            button.setBackground(currentColor);
            colorChooser.setColor(currentColor);
            dialog.setVisible(true);

            fireEditingStopped();

         } else {
            currentColor = colorChooser.getColor();
         }
      }
   }

   public Object getCellEditorValue() {
      return currentColor;
   }

   public Component getTableCellEditorComponent(JTable table, Object value,
         boolean isSelected, int row, int column) {
      currentColor = (Color) value;
      return button;
   }
}

class ColorCellRenderer implements TableCellRenderer {
   private static final int IMG_WIDTH = 70;
   private static final int IMG_HEIGHT = 20;
   private JLabel label = new JLabel();

   @Override
   public Component getTableCellRendererComponent(JTable table, Object value,
         boolean arg2, boolean arg3, int arg4, int arg5) {
      Color color = (Color) value;
      BufferedImage img = new BufferedImage(IMG_WIDTH, IMG_HEIGHT,
            BufferedImage.TYPE_INT_RGB);
      Graphics g = img.getGraphics();
      g.setColor(color);
      g.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
      g.dispose();
      ImageIcon icon = new ImageIcon(img);
      label.setIcon(icon);
      return label;
   }

}

class MyTableModel extends DefaultTableModel {
   private static final String[] COLUMN_NAMES = { "Station #", "Name",
         "avg Time", "Buffer", "Buffer Parts", "Color" };

   public MyTableModel(Object[][] data) {
      super(data, COLUMN_NAMES);
   }

   @Override
   public boolean isCellEditable(int row, int col) {

      if (col == 0) {
         return false;
      } else if (col == 4) {
         boolean di = (Boolean) getValueAt(row, (col - 1));
         if (!di) {
            return false;
         } else {
            return true;
         }
      } else {
         return true;
      }
   }

   public void printDebugData() {
      int numRows = getRowCount();
      int numCols = getColumnCount();

      for (int i = 0; i < numRows; i++) {
         System.out.print("    row " + i + ":");
         for (int j = 0; j < numCols; j++) {
            Object datum = getValueAt(i, j);
            // System.out.print("  " + data[i][j]);
            System.out.print("  " + datum);
         }
         System.out.println();
      }
      System.out.println("--------------------------");
   }
}
于 2012-07-19T03:46:26.240 回答