2012-08-08 9 views
10

ich eine JTable mit einer benutzerdefinierten Tabelle erstellt haben, machen und benutzerdefinierte Zellen-Editor, dieWie benutzerdefinierten JTable Zellen-Editor und CellRenderers verwenden

das Ergebnis im Bild gibt

enter image description here

ich die Platte in der gezeigt erstellt erste Tabellenzellen verwenden eine separate Klasse, die JPanel erweitert. und Tabellenwerte wie

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

hinzufügen Und das ist meine Tabelle benutzerdefinierte Klasse diese Tabelle zu erstellen,

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

Mein Problem gedacht wird das Panel gezeigt wird, wie ich erwartete ich kann nicht in den Typ Textfeld oder ändern Sie das Kontrollkästchen oder klicken Sie auf die Schaltfläche. Bitte sag mir, wie ich das lösen kann.

Antwort

8

haben hinzuzufügen richtige LayoutManager, Editable/non_Editable Eigenschaften für bereits sichtbar JPanel

beginnen lassen genießen

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

Beenden der Bearbeitung gehört in den Editor, nicht in das Panel. Auch, das Modell von außen actionListener ist ... streitbar ;-) – kleopatra

+0

vielen Dank für den tollen Fang, BTW dieser Code wird von Ihrer Ehrlichkeit mehr als 3 Mal überarbeitet, ich habe versucht, bewegen und Action von JTable von Rob (Ich denke, dass nichts besseres, frei und einfacher um), keine Änderungen und Veranstaltung sind ziemlich similair, – mKorbel

+0

Thanx viel mKorbel – Harsha

12

ich stark die Funktionalität wiederzuverwenden würde vorschlagen, in der Standardtabelle Renderer und Editoren zur Verfügung gestellt, da es viele Dinge falsch mit Ihrem Code

  1. Bitte teilen Sie Ihren Editor Renderer und Tischmodell ist. Sie alle in der gleichen Klasse zu haben ist einfach komisch
  2. Erstellen Sie für Ihren Renderer nicht jedes Mal neue Instanzen eines Component. Stattdessen die gleiche Komponente wiederverwenden und ändern nur, dass Component im getTableCellRendererComponent Methode
  3. Das Gleiche gilt für den Editor Component
  4. einen Standard-Editor erweitern stattdessen die Methoden mit UnsupportedOperationException s der Implementierung oder nur leere String s Rückkehr

Was ist, wenn Sie wollen, geben Sie einen anderen Editor als ein Textfeld, c:

zu meinem her Punkt, ein kleines Zitat aus dem Editors part in the JTable tutorial Back-up Heck Box oder Combo Box? Da der DefaultCellEditor keine anderen Komponententypen unterstützt, müssen Sie etwas mehr arbeiten. Sie müssen eine Klasse erstellen, die die TableCellEditor-Schnittstelle implementiert. Die AbstractCellEditor-Klasse ist eine gute zu verwendende Superklasse. Es implementiert die Superschnittstelle von TableCellEditor, CellEditor, und erspart Ihnen die Implementierung des Ereignisauslösungscodes, der für Zelleditoren erforderlich ist.

Ihre Cell-Editor-Klasse muss mindestens zwei Methoden definieren - getCellEditorValue und getTableCellEditorComponent. Die Methode "getCellEditorValue", die von CellEditor benötigt wird, gibt den aktuellen Wert der Zelle zurück. Die getTableCellEditorComponent-Methode, die von TableCellEditor benötigt wird, sollte die Komponente konfigurieren und zurückgeben, die Sie als Editor verwenden möchten.

erklärt Wie klar es Sie das Ereignis Abfeuern Code implementieren müssen:

Sie sich die Mühe Speichern der Veranstaltung der Implementierung erforderlichen Code für Zelleditoren Brennen.

die Sie eindeutig vernachlässigt haben.Deshalb mein Rat von AbstractCellEditor anstelle der Implementierung der Schnittstelle von Grund auf neu

+0

können Sie bitte ein vollständiges Beispiel geben mit Code? – partho

Verwandte Themen