2012-08-08 15 views
10

Utworzono JTable z niestandardowych tabeli renderowania i redaktor komórek niestandardowego, który daje wynik w obrazieJak korzystać z edytora komórek niestandardowych JTable i renderujący komórki

enter image description here

stworzyłem panel pokazany w pierwsze komórki tabeli używające oddzielnej klasy rozszerzającej JPanel. i dodać wartości tabeli jak

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

I to jest mój stół zwyczaj klasa stworzyć tę tabelę,

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

Mój problem jest uważany panel jest pokazane, jak się spodziewałem, że nie można wpisać w pole tekstowe lub zmień pole wyboru lub kliknij przycisk. proszę powiedz mi, jak rozwiązać ten problem.

Odpowiedz

8

trzeba dodać odpowiednie LayoutManager, Editable/non_Editable właściwości już widoczny JPanel

pozwolić cieszyć

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

zatrzymanie edycji należy do edytora, a nie do panelu. Również zepsucie modelu z zewnątrz actionListener jest ... dyskusyjne ;-) – kleopatra

+0

dziękuję za wspaniały połów, przy okazji ten kod jest poprawiony przez twoją szczerość ponad 3 razy, próbowałem przenieść i użyć Action z JTable autorstwa Roba (Myślę, że nie ma nic lepszego, łatwiejszego i prostszego), żadne zmiany i wydarzenie nie są uruchamiane w całkiem podobny sposób, – mKorbel

+0

Niż dużo mKorbel – Harsha

12

bym zdecydowanie wskazują na ponowne wykorzystanie funkcjonalności udostępnianych w renderujących domyślny stołowych i wydawców, jak istnieje wiele rzeczy nie tak z kodem

  1. Proszę podzielić edytor renderujący i modelu stołowego. Mając je wszystkie w tej samej klasie jest po prostu dziwne
  2. Dla swojego renderer, nie tworzyć nowych wystąpień Component za każdym razem. Zamiast używać tego samego składnika i po prostu zmodyfikować tę Component w metodzie getTableCellRendererComponent
  3. samo dotyczy edytora Component
  4. Extend domyślny edytor zamiast wdrażania metod z UnsupportedOperationException s lub po prostu wraca pusty String s

back-up mojego punktu naprzód, trochę cytatów z Editors part in the JTable tutorial:

Co zrobić, jeśli chcesz określić edytor inny niż pole tekstowe, c heck box lub combo box? Ponieważ DefaultCellEditor nie obsługuje innych typów komponentów, musisz zrobić trochę więcej pracy. Musisz utworzyć klasę, która implementuje interfejs TableCellEditor. Klasa AbstractCellEditor jest dobrą superklasą do użycia. Implementuje superinterface TableCellEditor, CellEditor, oszczędzając ci kłopotów z implementacją kodu uruchamiania zdarzenia niezbędnego dla edytorów komórek.

Twoja klasa edytora komórek musi zdefiniować co najmniej dwie metody - getCellEditorValue i getTableCellEditorComponent. Metoda getCellEditorValue wymagana przez narzędzie CellEditor zwraca bieżącą wartość komórki. Metoda getTableCellEditorComponent wymagana przez TableCellEditor powinna skonfigurować i zwrócić komponent, który ma być używany jako edytor.

Jak jasno wyjaśnił, że musi zaimplementować kod wypalania zdarzeń:

oszczędzając kłopotów z realizacji zdarzenia wypalania kod niezbędny dla redaktorów komórkowych.

którą wyraźnie zaniedbaliśmy.Dlatego radzę zacząć od AbstractCellEditor zamiast wykonania interfejsu od podstaw

+0

może Pan podać pełny przykład z kod? – partho

Powiązane problemy