【问题标题】:JTable: setCellEditor and setCellRenderer works but setDefaultEditor and setDefaultRenderer, getColumnClassJTable:setCellEditor 和 setCellRenderer 有效,但 setDefaultEditor 和 setDefaultRenderer、getColumnClass
【发布时间】:2017-12-19 19:31:43
【问题描述】:

是的,我检查了我的代码:

Using TableCellRenderer and getColumnClass together , JSlider in JTable

我为存储在 Cells 上的许多自定义组件实现了我自己的渲染器和编辑器。

    final String[] Titles = {"PanelTypeOne", "PanelTypeTwo"};
    final Object[][] Objects = {
      { new PanelTypeOneData(true), new PanelTypeTwoData(false) },
      { new PanelTypeOneData(false), new PanelTypeTwoData(true) },
      { new PanelTypeOneData(false), new PanelTypeTwoData(false) }
    };

我实现了三个按钮来显示问题

bEmpty 放置一个新的 Empty JTable

    JButton bEmpty = new JButton("Empty");
    bEmpty.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tEmpty Pressed!\n\n");
        jsp.setViewportView(new JTable());
      }
    });

bColumn 放置一个新的JTable,根据列(标识符)分配一个渲染器和编辑器。

    JButton bColumn = new JButton("Column");
    bColumn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tColumn Pressed!\n\n");
        JTable table = new JTable(new MyTableModel(Objects, Titles)) {
          @Override public void updateUI() {
            super.updateUI();
            getColumn("PanelTypeOne").setCellEditor(new PanelTypeOneEditor());
            getColumn("PanelTypeOne").setCellRenderer(new PanelTypeOneRenderer());
            getColumn("PanelTypeTwo").setCellEditor(new PanelTypeTwoEditor());
            getColumn("PanelTypeTwo").setCellRenderer(new PanelTypeTwoRenderer());
          }
        };
        jsp.setViewportView(table);
      }
    });

按预期工作!

bDefault 使用setDefaultEditorsetDefaultRenderer 方法按类型分配一个新的JTable

    JButton bDefault = new JButton("Default");
    bDefault.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tDefault Pressed!\n\n");
        JTable table = new JTable(new MyTableModel(Objects, Titles)) {
          @Override public void updateUI() {
            super.updateUI();
            setDefaultEditor(PanelTypeOne.class, new PanelTypeOneEditor());
            setDefaultRenderer(PanelTypeOne.class, new PanelTypeOneRenderer());
            setDefaultEditor(PanelTypeTwo.class, new PanelTypeTwoEditor());
            setDefaultRenderer(PanelTypeTwo.class, new PanelTypeTwoRenderer());
          }
        };
        jsp.setViewportView(table);
      }
    });

但工作不完美。

我想可能是我自定义的getColumnClass 方法,这里是代码:

  @Override public Class getColumnClass(int col) {
    System.out.println("data[0][" + col + "].getClass():" + data[0][col].getClass());
    System.out.println("getValueAt(0, " + col + ").getClass():" + getValueAt(0, col).getClass());
    if (data != null) {
      if (data.length > 0) {
        if (data[0][col] instanceof PanelTypeOne) {
          return PanelTypeOne.class;
        }
        if (data[0][col] instanceof PanelTypeOneData) {
          return PanelTypeOne.class;
        }
        if (data[0][col] instanceof PanelTypeTwo) {
          return PanelTypeTwo.class;
        }
        if (data[0][col] instanceof PanelTypeTwoData) {
          return PanelTypeTwoData.class;
        }
        return data[0][col].getClass();
        //return getValueAt(0, col).getClass();
      }
    }
    return Object.class;
  }

问题:

  • 使用setDefaultEditorsetDefaultRenderer 方法是否有限制? (当然没有)
  • 使用它们有什么错误? (也许不是)
  • 我的getColumnClass 方法呢?

打印输出:

$ java -cp "/.../..." TableSetDefault


  Empty Pressed!




  Column Pressed!




  Default Pressed!


data[0][0].getClass():class PanelTypeOneData
getValueAt(0, 0).getClass():class PanelTypeOneData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData
data[0][0].getClass():class PanelTypeOneData
getValueAt(0, 0).getClass():class PanelTypeOneData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData
data[0][0].getClass():class PanelTypeOneData
getValueAt(0, 0).getClass():class PanelTypeOneData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData
data[0][1].getClass():class PanelTypeTwoData
getValueAt(0, 1).getClass():class PanelTypeTwoData


  Empty Pressed!


$ 

这里是完整的源代码:

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

public class TableSetDefault extends JFrame {
   final JScrollPane jsp = new JScrollPane();

  public TableSetDefault()  {
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setSize(600, 300);
    setVisible(true);
    setLocationRelativeTo(null);
  }
  public static void setLAF(Container container, String laf) {
    try {
      UIManager.setLookAndFeel(laf);
      UIManager.put("Table.intercellSpacing", new Dimension(1, 1));
    } catch (ClassNotFoundException | InstantiationException
        | IllegalAccessException | UnsupportedLookAndFeelException e) {
    }
    SwingUtilities.updateComponentTreeUI(container);
  }
  static final JFrame frame = new JFrame();

  public JComponent makeUI() {
    final String[] Titles = {"PanelTypeOne", "PanelTypeTwo"};
    final Object[][] Objects = {
      { new PanelTypeOneData(true), new PanelTypeTwoData(false) },
      { new PanelTypeOneData(false), new PanelTypeTwoData(true) },
      { new PanelTypeOneData(false), new PanelTypeTwoData(false) }
    };

    JPanel pH = new JPanel();
    pH.setLayout(new BoxLayout(pH, BoxLayout.LINE_AXIS));

    JPanel pV = new JPanel();
    pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));

    JButton bEmpty = new JButton("Empty");
    bEmpty.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tEmpty Pressed!\n\n");
        jsp.setViewportView(new JTable());
      }
    });
    JButton bColumn = new JButton("Column");
    bColumn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tColumn Pressed!\n\n");
        JTable table = new JTable(new MyTableModel(Objects, Titles)) {
          @Override public void updateUI() {
            super.updateUI();
            getColumn("PanelTypeOne").setCellEditor(new PanelTypeOneEditor());
            getColumn("PanelTypeOne").setCellRenderer(new PanelTypeOneRenderer());
            //getColumn("PanelTypeTwo").setCellEditor(new CellPanelTypeTwo());
            //getColumn("PanelTypeTwo").setCellRenderer(new CellPanelTypeTwo());
            getColumn("PanelTypeTwo").setCellEditor(new PanelTypeTwoEditor());
            getColumn("PanelTypeTwo").setCellRenderer(new PanelTypeTwoRenderer());
          }
        };
        jsp.setViewportView(table);
      }
    });
    JButton bDefault = new JButton("Default");
    bDefault.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println("\n\n\tDefault Pressed!\n\n");
        JTable table = new JTable(new MyTableModel(Objects, Titles)) {
          @Override public void updateUI() {
            super.updateUI();
            setDefaultEditor(PanelTypeOne.class, new PanelTypeOneEditor());
            setDefaultRenderer(PanelTypeOne.class, new PanelTypeOneRenderer());
            //setDefaultEditor(PanelTypeTwo.class, new CellPanelTypeTwo());
            //setDefaultRenderer(PanelTypeTwo.class, new CellPanelTypeTwo());
            setDefaultEditor(PanelTypeTwo.class, new PanelTypeTwoEditor());
            setDefaultRenderer(PanelTypeTwo.class, new PanelTypeTwoRenderer());
          }
        };
        jsp.setViewportView(table);
      }
    });
    pH.add(bEmpty);
    pH.add(bColumn);
    pH.add(bDefault);

    pV.add(pH);
    pV.add(jsp);
    return pV;
  }

  public static void main(String... args) {
    try {
      UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
      UIManager.put("Table.intercellSpacing", new Dimension(1, 1));
    } catch (ClassNotFoundException | InstantiationException
        | IllegalAccessException | UnsupportedLookAndFeelException e) { }
    EventQueue.invokeLater(() -> {
      TableSetDefault f = new TableSetDefault();
      f.getContentPane().add(f.makeUI());
    });
  }
}

class PanelTypeOne extends JPanel {
  private final JCheckBox cbEnabled = new JCheckBox("TypeOne");
  private final JPanel panel = new JPanel();
  PanelTypeOne(PanelTypeOneData data) {
    super();
    panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
    panel.add(cbEnabled);
    cbEnabled.setFont(new Font("Monospaced", Font.PLAIN, 10));
    setData(data);
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    add(panel);
  }
  public PanelTypeOneData getData() {
    return new PanelTypeOneData(cbEnabled.isSelected());
  }
  public void setData(PanelTypeOneData data) {
    for (ActionListener al : cbEnabled.getActionListeners()) {
      cbEnabled.removeActionListener(al);
    }
    cbEnabled.addActionListener((ActionEvent e) -> {
      System.out.println("Class:" + getClass().getName() + ":\tChecked at " + System.nanoTime());
    });
  }
}

class PanelTypeOneData {
  private boolean enabled = false;
  PanelTypeOneData(Boolean enabled) { this.enabled = enabled; }
  public void setValue(Boolean enabled) { this.enabled = enabled; }
  public boolean getValue() { return enabled; }
}

class PanelTypeTwo extends JPanel {
  private final JCheckBox cbEnabled = new JCheckBox("TypeTwo");
  private final JPanel panel = new JPanel();
  PanelTypeTwo(PanelTypeTwoData data) {
    super();
    panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
    panel.add(cbEnabled);
    cbEnabled.setFont(new Font("Monospaced", Font.PLAIN, 10));
    setData(data);
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    add(panel);
  }
  public PanelTypeTwoData getData() {
    return new PanelTypeTwoData(cbEnabled.isSelected());
  }
  public void setData(PanelTypeTwoData data) {
    for (ActionListener al : cbEnabled.getActionListeners()) {
      cbEnabled.removeActionListener(al);
    }
    cbEnabled.addActionListener((ActionEvent e) -> {
      System.out.println("Class:" + getClass().getName() + ":\tChecked at " + System.nanoTime());
    });
  }
}

class PanelTypeTwoData {
  private boolean enabled = false;
  PanelTypeTwoData(Boolean enabled) { this.enabled = enabled; }
  public void setValue(Boolean enabled) { this.enabled = enabled; }
  public boolean getValue() { return enabled; }
}

/*
class CellPanelTypeOne extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
  private PanelTypeOne pt1e = new PanelTypeOne(new PanelTypeOneData(false));
  private PanelTypeOne pt1r = new PanelTypeOne(new PanelTypeOneData(false));
  @Override public Object getCellEditorValue() {
    return pt1e.getData();
  }
  @Override public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    pt1e.setData((PanelTypeOneData) value);
    return pt1e;
  }
  @Override public Component getTableCellRendererComponent(JTable table, 
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    pt1r.setData((PanelTypeOneData)value);
    return pt1r;
  }
}
*/

/*
class CellPanelTypeTwo extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {
  private PanelTypeTwo pt2e = new PanelTypeTwo(new PanelTypeTwoData(false));
  private PanelTypeTwo pt2r = new PanelTypeTwo(new PanelTypeTwoData(false));
  @Override public Object getCellEditorValue() {
    return pt2e.getData();
  }
  @Override public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    pt2e.setData((PanelTypeTwoData) value);
    return pt2e;
  }
  @Override public Component getTableCellRendererComponent(JTable table, 
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    pt2e.setData((PanelTypeTwoData)value);
    return pt2e;
  }
}
*/

class PanelTypeOneEditor extends AbstractCellEditor implements TableCellEditor {
  private PanelTypeOne pt1e = new PanelTypeOne(new PanelTypeOneData(false));
  @Override public Object getCellEditorValue() {
    return pt1e.getData();
  }
  @Override public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    pt1e.setData((PanelTypeOneData) value);
    return pt1e;
  }
}

class PanelTypeTwoEditor extends AbstractCellEditor implements TableCellEditor {
  private PanelTypeTwo pt2e = new PanelTypeTwo(new PanelTypeTwoData(false));
  @Override public Object getCellEditorValue() {
    return pt2e.getData();
  }
  @Override public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    pt2e.setData((PanelTypeTwoData) value);
    return pt2e;
  }
}

//class PanelTypeOneRenderer extends JLabel implements TableCellRenderer {
class PanelTypeOneRenderer extends DefaultTableCellRenderer  {
  private PanelTypeOne pt1r = new PanelTypeOne(new PanelTypeOneData(false));
  @Override public Component getTableCellRendererComponent(JTable table, 
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    pt1r.setData((PanelTypeOneData)value);
    return pt1r;
  }
}

class PanelTypeTwoRenderer extends DefaultTableCellRenderer  {
  private PanelTypeTwo pt2r = new PanelTypeTwo(new PanelTypeTwoData(false));
  @Override public Component getTableCellRendererComponent(JTable table, 
      Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    pt2r.setData((PanelTypeTwoData)value);
    return pt2r;
  }
}

//class MyTableModel extends AbstractTableModel {
class MyTableModel extends DefaultTableModel {
  private Object[][] data;
  private String[] titles;
  public MyTableModel(Object[][] data, String[] titles) {
    this.data = data;
    this.titles = titles;
  }
  @Override public Object getValueAt(int row, int col) {
    return data[row][col];
  }
  @Override public int getColumnCount() {
    return ((titles == null) ? 0 : titles.length);
  }
  @Override public int getRowCount() {
    return ((data == null) ? 0 : data.length);
  }
  @Override public Class getColumnClass(int col) {
    System.out.println("data[0][" + col + "].getClass():" + data[0][col].getClass());
    System.out.println("getValueAt(0, " + col + ").getClass():" + getValueAt(0, col).getClass());
    if (data != null) {
      if (data.length > 0) {
        if (data[0][col] instanceof PanelTypeOne) {
          return PanelTypeOne.class;
        }
        if (data[0][col] instanceof PanelTypeOneData) {
          return PanelTypeOne.class;
        }
        if (data[0][col] instanceof PanelTypeTwo) {
          return PanelTypeTwo.class;
        }
        if (data[0][col] instanceof PanelTypeTwoData) {
          return PanelTypeTwoData.class;
        }
        return data[0][col].getClass();
        //return getValueAt(0, col).getClass();
      }
    }
    return Object.class;
  }
  @Override public boolean isCellEditable(int row, int col) {
    if (col < 0) {
      return false;
    } else {
      return true;
    }
  }
  @Override public void setValueAt(Object value, int row, int col) {
    data[row][col] = value;
    fireTableCellUpdated(row, col);
  }
  @Override public String getColumnName(int col) {
    return titles[col];
  }

}

【问题讨论】:

    标签: jtable tablecellrenderer defaulttablemodel tablecelleditor


    【解决方案1】:

    MyTableModel 内部的类更改 getColumnClass 方法。

    表格模式存储数据!!!

      @Override public Class getColumnClass(int col) {
        System.out.println("data[0][" + col + "].getClass():" + data[0][col].getClass());
        System.out.println("getValueAt(0, " + col + ").getClass():" + getValueAt(0, col).getClass());
        if (data != null) {
          if (data.length > 0) {
            //if (data[0][col] instanceof PanelTypeOne) {
            //  return PanelTypeOne.class;
            //}
            if (data[0][col] instanceof PanelTypeOneData) {
              return PanelTypeOne.class;
            }
            if (data[0][col] instanceof PanelTypeTwoData) {
              return PanelTypeTwo.class;
            }
            //if (data[0][col] instanceof PanelTypeTwoData) {
            //  return PanelTypeTwoData.class;
            //}
            return data[0][col].getClass();
            //return getValueAt(0, col).getClass();
          }
        }
        return Object.class;
      }
    

    【讨论】:

      猜你喜欢
      • 2014-06-15
      • 1970-01-01
      • 2013-11-05
      • 2021-12-21
      • 2011-07-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      相关资源
      最近更新 更多