2012-08-08 25 views
10

He creado un JTable con una tabla personalizada rendir y editor de celdas personalizado que da el resultado en la imagenCómo utilizar editor de celda personalizado JTable y procesador de celdas

enter image description here

creé el panel que se muestra en el primeras celdas de tabla usando una clase separada que extendió JPanel. y añadir valores de la tabla como,

 tbl.setCellEditor(new customCell()); 
     tbl.getColumnModel().getColumn(0).setCellRenderer(new customCell()); 

     DefaultTableModel dtm = (DefaultTableModel) tbl.getModel(); 

     Vector v = new Vector(); 
     v.add(new Panel()); 
     v.add("Test"); 
     dtm.addRow(v); 

     v.clear(); 
     v.add(new Panel()); 
     v.add("Test 2"); 
     dtm.addRow(v); 

Y esta es mi clase personalizada tabla para crear esta tabla,

class customCell extends DefaultTableModel implements TableCellRenderer, TableCellEditor { 

     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      Panel p = new Panel();    
      table.setRowHeight(row, p.getHeight()); 
      return p; 
     } 

     public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 

      return new Panel(); 
     } 

     public Object getCellEditorValue() { 
      return ""; 
     } 

     public boolean isCellEditable(EventObject anEvent) { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     public boolean shouldSelectCell(EventObject anEvent) { 
      return true; 
     } 

     @Override 
     public boolean isCellEditable(int rowIndex, int columnIndex) { 
      return true; 
     } 

     public boolean stopCellEditing() { 
      return true; 
     } 

     public void cancelCellEditing() { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     public void addCellEditorListener(CellEditorListener l) { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 

     public void removeCellEditorListener(CellEditorListener l) { 
      throw new UnsupportedOperationException("Not supported yet."); 
     } 
    } 

Mi problema se piensa que el panel se muestra como que esperaba que no puedo escribir en el campo de texto o casilla de verificación de cambio o haga clic en el botón. por favor dime como resolver esto.

Respuesta

8

han de añadir adecuados LayoutManager, Editable/non_Editable propiedades para la ya visible JPanel

vamos a disfrutar

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

public class PanelInTable { 

    private JFrame frame; 
    private JTable compTable = null; 
    private PanelTableModel compModel = null; 
    private JButton addButton = null; 

    public static void main(String args[]) { 
     try { 
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
      //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } catch (Exception fail) { 
     } 
     SwingUtilities.invokeLater(() -> { 
      new PanelInTable().makeUI(); 
     }); 
    } 

    public void makeUI() { 
     compTable = CreateCompTable(); 
     JScrollPane CompTableScrollpane = new JScrollPane(compTable, 
       JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
       JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 
     JPanel bottomPanel = CreateBottomPanel(); 
     frame = new JFrame("Comp Table Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(CompTableScrollpane, BorderLayout.CENTER); 
     frame.add(bottomPanel, BorderLayout.SOUTH); 
     frame.setPreferredSize(new Dimension(800, 400)); 
     frame.setLocation(150, 150); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public JTable CreateCompTable() { 
     compModel = new PanelTableModel(); 
     compModel.addRow(); 
     JTable table = new JTable(compModel); 
     table.setRowHeight(new CompCellPanel().getPreferredSize().height); 
     table.setTableHeader(null); 
     PanelCellEditorRenderer PanelCellEditorRenderer = new PanelCellEditorRenderer(); 
     table.setDefaultRenderer(Object.class, PanelCellEditorRenderer); 
     table.setDefaultEditor(Object.class, PanelCellEditorRenderer); 
     return table; 
    } 

    public JPanel CreateBottomPanel() { 
     addButton = new JButton("Add Comp"); 
     addButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       Object source = ae.getSource(); 
       if (source == addButton) { 
        compModel.addRow(); 
       } 
      } 
     }); 
     JPanel panel = new JPanel(new GridBagLayout()); 
     panel.add(addButton); 
     return panel; 
    } 
} 

class PanelCellEditorRenderer extends AbstractCellEditor implements 
     TableCellRenderer, TableCellEditor { 

    private static final long serialVersionUID = 1L; 
    private CompCellPanel renderer = new CompCellPanel(); 
    private CompCellPanel editor = new CompCellPanel(); 

    @Override 
    public Component getTableCellRendererComponent(JTable table, Object value, 
      boolean isSelected, boolean hasFocus, int row, int column) { 
     renderer.setComp((Comp) value); 
     return renderer; 
    } 

    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, 
      boolean isSelected, int row, int column) { 
     editor.setComp((Comp) value); 
     return editor; 
    } 

    @Override 
    public Object getCellEditorValue() { 
     return editor.getComp(); 
    } 

    @Override 
    public boolean isCellEditable(EventObject anEvent) { 
     return true; 
    } 

    @Override 
    public boolean shouldSelectCell(EventObject anEvent) { 
     return false; 
    } 
} 

class PanelTableModel extends DefaultTableModel { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public int getColumnCount() { 
     return 1; 
    } 

    public void addRow() { 
     super.addRow(new Object[]{new Comp(0, 0, "", "")}); 
    } 
} 

class Comp { 

    public int type; 
    public int relation; 
    public String lower; 
    public String upper; 

    public Comp(int type, int relation, String lower, String upper) { 
     this.type = type; 
     this.relation = relation; 
     this.lower = lower; 
     this.upper = upper; 
    } 
} 

class CompCellPanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private JLabel labelWith = new JLabel("With "); 
    private JComboBox typeCombo = new JComboBox(new Object[] 
    {"height", "length", "volume"}); 
    private JComboBox relationCombo = new JComboBox(new Object[] 
    {"above", "below", "between"}); 
    private JTextField lowerField = new JTextField(); 
    private JLabel labelAnd = new JLabel(" and "); 
    private JTextField upperField = new JTextField(); 
    private JButton removeButton = new JButton("remove"); 

    public CompCellPanel() { 
     setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 
     relationCombo.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       enableUpper(relationCombo.getSelectedIndex() == 2); 
      } 
     }); 
     enableUpper(false); 
     removeButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JTable table = (JTable) SwingUtilities.getAncestorOfClass(
         JTable.class, (Component) e.getSource()); 
       int row = table.getEditingRow(); 
       table.getCellEditor().stopCellEditing(); 
       ((DefaultTableModel) table.getModel()).removeRow(row); 
      } 
     }); 
     add(labelWith); 
     add(typeCombo); 
     add(relationCombo); 
     add(lowerField); 
     add(labelAnd); 
     add(upperField); 
     add(Box.createHorizontalStrut(100)); 
     add(removeButton); 
    } 

    private void enableUpper(boolean enable) { 
     labelAnd.setEnabled(enable); 
     upperField.setEnabled(enable); 
    } 

    public void setComp(Comp Comp) { 
     typeCombo.setSelectedIndex(Comp.type); 
     relationCombo.setSelectedIndex(Comp.relation); 
     lowerField.setText(Comp.lower); 
     upperField.setText(Comp.upper); 
     enableUpper(Comp.relation == 2); 
    } 

    public Comp getComp() { 
     return new Comp(typeCombo.getSelectedIndex(), 
       relationCombo.getSelectedIndex(), 
       lowerField.getText(), upperField.getText()); 
    } 
} 
+1

detener la edición pertenece al editor, no al panel. Además, estropear el modelo desde el exterior actionListener es ... discutible ;-) – kleopatra

+0

gracias por la gran captura, por cierto, este código es revisado por su honestidad más de 3 veces, traté de mover y usar Action from JTable made by Rob (Creo que nada mejor, gratis y más simple), no se han producido cambios ni eventos muy similares, – mKorbel

+0

Muchas gracias mKorbel – Harsha

12

Me gustaría sugerir fuertemente para reutilizar la funcionalidad hecho disponible en los procesadores de la tabla por defecto y editores, ya que hay muchas cosas mal con su código

  1. favor dividir su editor, procesador y el modelo de mesa. Tenerlos a todos en la misma clase es simplemente extraño
  2. Para su procesador, no cree nuevas instancias de Component cada vez. En su lugar, volver a utilizar el mismo componente y simplemente modificar esa Component en el método getTableCellRendererComponent
  3. mismo ocurre con el editor de Component
  4. Extender un editor por defecto en lugar de aplicar los métodos con UnsupportedOperationException s o que acaban de volver vacío String s

para respaldar mi punto a otro, una pequeña cita del Editors part in the JTable tutorial:

¿Qué pasa si desea especificar un editor que no sea un campo de texto, c diablos caja, o cuadro combinado? Como DefaultCellEditor no admite otros tipos de componentes, debe hacer un poco más de trabajo. Necesita crear una clase que implemente la interfaz TableCellEditor. La clase AbstractCellEditor es una buena superclase para usar. Implementa la superinterfaz de TableCellEditor, CellEditor, lo que le ahorra la molestia de implementar el código de activación de eventos necesario para los editores de células.

Su clase de editor de celda necesita definir al menos dos métodos: getCellEditorValue y getTableCellEditorComponent. El método getCellEditorValue, requerido por CellEditor, devuelve el valor actual de la celda. El método getTableCellEditorComponent, requerido por TableCellEditor, debe configurar y devolver el componente que desea usar como editor.

Como se ha explicado claramente que no se debe implementar el código de disparar eventos:

que le ahorra la molestia de poner en práctica el evento de disparo código necesario para editores de celdas.

que claramente descuidó.Por lo tanto, mi consejo a empezar desde AbstractCellEditor en lugar de implementar la interfaz desde cero

+0

puede por favor dar un ejemplo completo con ¿código? – partho

Cuestiones relacionadas