简体   繁体   English

JTable:setCellEditor和setCellRenderer可以工作,但是setDefaultEditor和setDefaultRenderer,getColumnClass

[英]JTable: setCellEditor and setCellRenderer works but setDefaultEditor and setDefaultRenderer, getColumnClass

Yes, I review my code: 是的,我查看了我的代码:

Using TableCellRenderer and getColumnClass together , JSlider in JTable 一起使用TableCellRenderer和getColumnClass在JTable中 使用 JSlider

I'm implemented my Own Renderer and Editor for muy Custom Components stored on Cells. 我为存储在单元上的muy自定义组件实现了自己的渲染器和编辑器。

    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) }
    };

I'm implemented three buttons for show the problems 我实现了三个按钮来显示问题

bEmpty to put a new Empty JTable . 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 to put a new JTable assigning a Renderer and Editor according to Column (Identifier). bColumn放置一个新的JTable ,根据Column(标识符)分配一个Renderer和Editor。

    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);
      }
    });

Works like expected! 像预期的那样工作! getColumn

bDefault to put a new JTable assigning by type Class using setDefaultEditor and setDefaultRenderer methods. 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);
      }
    });

But is not working perfectly. 但是效果并不理想。 在此处输入图片说明

I think maybe is my custom getColumnClass method, here the code: 我想也许是我的自定义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;
  }

QUESTIONS: 问题:

  • Is there a limitation using setDefaultEditor , setDefaultRenderer methods? 使用setDefaultEditorsetDefaultRenderer方法是否有限制? (Sure not) . (当然不能)
  • What mistakes using them? 使用它们有什么错误? (Maybe not) . (也许不是)
  • What about of my getColumnClass method? 那我的getColumnClass方法呢?

The print Output: 打印输出:

$ 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!


$ 

Here Full Source Code: 这里完整的源代码:

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];
  }

}

inside of MyTableModel class change getColumnClass method. MyTableModel类的内部更改getColumnClass方法。

The table modes stores data!!! 表模式存储数据!!!

  @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;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM