CellRendererとCellEditor
ここまでに作ったレンダラーとエディタを統合し、少し汎用的なレンダラーとエディタを実装してみる。
■ソースコード
DefaultTableCellRendererとDefaultCellEditorを継承し、セルのオブジェクトに応じて、レンダラーとエディタを切り替えている。
なお、Dateオブジェクトのエディタは、以前作ったDateTimePickerをJDialogで囲ったCalendarDialogを作って使用している。
・MyTableCellRenderer.java
package test; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.util.Date; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.table.DefaultTableCellRenderer; public class MyTableCellRenderer extends DefaultTableCellRenderer{ private static final long serialVersionUID = 1L; private TableColorRenderer color; private TableFontRenderer font; private DateCellRenderer date; public MyTableCellRenderer(){ color=new TableColorRenderer(true); font=new TableFontRenderer(true); date=new DateCellRenderer(true); } @Override public Component getTableCellRendererComponent(JTable arg0, Object arg1, boolean arg2, boolean arg3, int arg4, int arg5) { if(arg1 instanceof Color){ return color.getTableCellRendererComponent(arg0, arg1, arg2, arg3, arg4, arg5); }else if(arg1 instanceof Boolean){ JCheckBox b=new JCheckBox(); b.setBackground(Color.WHITE); b.setSelected(((Boolean)arg1).booleanValue()); return b; }else if(arg1 instanceof Date){ return date.getTableCellRendererComponent(arg0, arg1, arg2, arg3, arg4, arg5); }else if(arg1 instanceof Font){ font.setBackground(Color.WHITE); return font.getTableCellRendererComponent(arg0, arg1, arg2, arg3, arg4, arg5); }else if(arg1 instanceof JComboBox){ JComboBox c=(JComboBox)arg1; return super.getTableCellRendererComponent(arg0, c.getSelectedItem(), arg2, arg3, arg4, arg5); }else if(arg1 instanceof JComponent){ return (JComponent)arg1; }else{ return super.getTableCellRendererComponent(arg0, arg1, arg2, arg3, arg4, arg5); } } }
・MyTableCellEditor.java
package test; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.table.DefaultTableModel; public class MyTableCellEditor extends DefaultCellEditor { private static final long serialVersionUID = 1L; private Component comp; private TableColorEditor color; private TableFontEditor font; private CalendarDialog cal; private Object val; public MyTableCellEditor(){ super(new JTextField()); color=new TableColorEditor(); font=new TableFontEditor(); cal=new CalendarDialog(JOptionPane.getRootFrame()); } @Override public Object getCellEditorValue() { if(val instanceof Color){ return color.getCellEditorValue(); }else if(val instanceof Font){ return font.getCellEditorValue(); }else if(val instanceof Date){ return val; }else if(val instanceof Number){ try{ if(val instanceof Integer){ return Integer.parseInt(super.getCellEditorValue().toString()); }else if(val instanceof Float){ return Float.parseFloat(super.getCellEditorValue().toString()); }else if(val instanceof Double){ return Double.parseDouble(super.getCellEditorValue().toString()); }else if(val instanceof Long){ return Long.parseLong(super.getCellEditorValue().toString()); }else{ return Double.parseDouble(super.getCellEditorValue().toString()); } }catch(NumberFormatException ne){ JOptionPane.showMessageDialog(comp,"NumberFormatException","",JOptionPane.ERROR_MESSAGE); return val; } }else{ if(comp instanceof JCheckBox){ if(((JCheckBox)comp).isSelected()){ return Boolean.TRUE; }else{ return Boolean.FALSE; } }else if(comp instanceof JTextField){ return ((JTextField)comp).getText(); }else if(comp instanceof JComboBox){ return (JComboBox)comp; }else if(comp instanceof JButton){ return (JButton)comp; }else if(comp instanceof JLabel){ return (JLabel)comp; }else{ return super.getCellEditorValue(); } } } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if(value instanceof Boolean){ JCheckBox b=new JCheckBox(); b.setBackground(Color.WHITE); b.setSelected(((Boolean)value).booleanValue()); comp=b; val=value; return comp; }else if(value instanceof Font){ val=value; return font.getTableCellEditorComponent(table, value, isSelected, row, column); }else if(value instanceof Date){ final JTable tt=table; final int rr=row; final int cc=column; final Object xx=value; JButton tmp=new JButton(((Date)value).toString()); tmp.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { Date dd=(Date)tt.getModel().getValueAt(rr, cc); cal.setDate(dd); cal.setLocationRelativeTo(tt); cal.setVisible(true); Date d=cal.getDate(); if(d!=null){ val=d; }else{ val=xx; } } }); return tmp; }else if(value instanceof Color){ val=value; return color.getTableCellEditorComponent(table, value, isSelected, row, column); }else if(value instanceof JButton){ JButton tmp=new JButton(((JButton)value).getText()); ActionListener[] ac=((JButton)value).getActionListeners(); for(int i=0;i<ac.length;i++){ tmp.addActionListener(ac[i]); } comp=tmp; val=value; return comp; }else if(value instanceof JComboBox){ JComboBox tmp=new JComboBox(((JComboBox)value).getModel()); ActionListener[] ac=((JComboBox)value).getActionListeners(); for(int i=0;i<ac.length;i++){ tmp.addActionListener(ac[i]); } comp=tmp; val=value; return comp; }else if(value instanceof JLabel){ JLabel tmp=(JLabel)value; comp=tmp; val=tmp; return comp; }else{ val=value; comp=super.getTableCellEditorComponent(table,value,isSelected,row,column); return comp; } } public static void main(String[] args){ JFrame f=new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JTable tb=new JTable(); final DefaultTableModel model=new DefaultTableModel(){ private static final long serialVersionUID = 1L; @Override public boolean isCellEditable(int arg0, int arg1) { return (arg1==1); } }; model.setColumnCount(2); model.setRowCount(7); model.setColumnIdentifiers(new String[]{"Name","Value"}); tb.setDefaultEditor(Object.class, new MyTableCellEditor()); tb.setDefaultRenderer(Object.class, new MyTableCellRenderer()); model.setValueAt("Color", 0, 0); model.setValueAt(Color.RED, 0, 1); model.setValueAt("Font", 1, 0); model.setValueAt(tb.getFont(), 1, 1); model.setValueAt("Date", 2, 0); model.setValueAt(new Date(System.currentTimeMillis()), 2, 1); model.setValueAt("Button", 3, 0); model.setValueAt(new JButton("OK"), 3, 1); model.setValueAt("Number", 4, 0); model.setValueAt(123, 4, 1); model.setValueAt("String", 5, 0); model.setValueAt("晴れ", 5, 1); model.setValueAt("Boolean", 6, 0); model.setValueAt(true, 6, 1); tb.setModel(model); f.getContentPane().setLayout(new BorderLayout()); f.getContentPane().add(new JScrollPane(tb),BorderLayout.CENTER); f.setTitle("Test"); f.setSize(300,200); f.setLocationRelativeTo(null); f.setVisible(true); } }
■結果
実行結果は以下のとおり。
2列目のセルをクリックすると、オブジェクトに適合したエディタが呼び出されます。