2012-04-09 9 views
0

Ich habe eine JTable mit N Zeilen und 2 Spalten Ich muss eine benutzerdefinierte CellEditor-Klasse für den Zugriff auf den Dateneingang jeder Zelle mitImplementiert einen benutzerdefinierten CellEditor für eine JTable mit 2 Spalten (String, Integer) und n Zeilen

implementieren

table.getCellEditor(int row, int column).getCellEditorValue()

ich diese CellEditor Klasse haben

class MyEditor extends DefaultCellEditor { 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private JTextField textField; 
     private boolean valueSet; 
      public MyEditor() { 
      super(new JTextField()); 
      } 

      @Override 
      public boolean isCellEditable(EventObject eo) { 
       System.err.println("isCellEditable"); 
       if (eo instanceof KeyEvent) { 
        KeyEvent ke = (KeyEvent) eo; 
        System.err.println("key event: " + ke.getKeyChar()); 
        textField.setText(String.valueOf(ke.getKeyChar())); 
        valueSet = true; 
       } else { 
        valueSet = false; 
       } 
       return true; 
      } 
    } 

aber nicht genug verwendet, um die Daten in der richtigen Zellenposition für den Zugriff auf ... (und scheint, dass alle die Tabelle als Ganzes Zelle zu sehen ist)

Alle Beispiele, die ich gefunden habe, beziehen sich auf den Zelleneditor, um die Bearbeitungszelle zu blockieren, wenn die Eingabe nicht korrekt ist, aber alles klar genug ist, um das Problem zu lösen.

PS Wenn Sie versuchen wollen, im Detail zu sehen, wie die ganze Schnittstelle (nicht) ist es, den gesamten Code funktioniert dies: do

public class CompileDataJob extends JFrame { 
     private boolean DEBUG = false; 
    private JPanel contentPane; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        CompileDataJob frame = new CompileDataJob(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public CompileDataJob() { 
     setTitle("Inserisci i parametri dei lavori"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 551, 293); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 

     JPanel panel_1 = new JPanel(); 
     final JTable table = new JTable(new MyTableModel()); 

     JButton btnNewButton = new JButton(" OK "); 
     btnNewButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       try{ 
        DataJobManager.azzeraListaLavori(); 
        int numJob=DataJobManager.loadNumeroLavori(); 
        LinkedList<Job> listaLavori=new LinkedList<Job>(); 
        String id; 
        int time; 
        for (int rowIndex=0; rowIndex<numJob; rowIndex++){ 
          id=(String)(table.getCellEditor(rowIndex,0).getCellEditorValue()); 
          time=Integer.parseInt(((String)((table.getCellEditor(rowIndex, 1)).getCellEditorValue()))); 
          Job l=new Job(id,time); 
          listaLavori.add(l); 
        } 
         DataJobManager.saveListaLavori(listaLavori); 
         CompileDataJob.this.dispose(); 
         JOptionPane.showMessageDialog(CompileDataJob.this,"Data Saved"); 
       }catch(Exception ecc){ 
        JOptionPane.showMessageDialog(CompileDataJob.this,"Error during the saving."); 
       } 
      } 
     }); 
     panel_1.add(btnNewButton); 

     JButton btnNewButton_1 = new JButton("Cancel"); 
     btnNewButton_1.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       CompileDataJob.this.dispose(); 
      } 
     }); 

     JPanel panel = new JPanel(); 



     table.setDefaultEditor(Object.class,new MyEditor()); 

     table.setPreferredScrollableViewportSize(new Dimension(500, 70)); 
     table.setFillsViewportHeight(true); 
     table.getSelectionModel().addListSelectionListener(
       new ListSelectionListener() { 
        public void valueChanged(ListSelectionEvent event) { 
         int viewRow = table.getSelectedRow(); 
         JLabel statusText=new JLabel(); 
         if (viewRow < 0) { 
          //Selection got filtered away. 
          statusText.setText(""); 
         } else { 
          int modelRow = 
           table.convertRowIndexToModel(viewRow); 
          statusText.setText(
           String.format("Selected Row in view: %d. " + 
            "Selected Row in model: %d.", 
            viewRow, modelRow)); 
         } 
        } 
       } 
     ); 


       //Create the scroll pane and add the table to it. 
       JScrollPane scrollPane = new JScrollPane(table); 

         //Set up column sizes. 
         initColumnSizes(table); 

     panel_1.add(btnNewButton_1); 
     GroupLayout gl_contentPane = new GroupLayout(contentPane); 
     gl_contentPane.setHorizontalGroup(
      gl_contentPane.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_contentPane.createSequentialGroup() 
        .addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false) 
         .addComponent(panel_1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
         .addComponent(panel, GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE)) 
        .addContainerGap()) 
     ); 
     gl_contentPane.setVerticalGroup(
      gl_contentPane.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_contentPane.createSequentialGroup() 
        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 213, GroupLayout.PREFERRED_SIZE) 
        .addPreferredGap(ComponentPlacement.RELATED, 61, Short.MAX_VALUE) 
        .addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) 
     ); 
     GroupLayout gl_panel = new GroupLayout(panel); 
     gl_panel.setHorizontalGroup(
      gl_panel.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_panel.createSequentialGroup() 
        .addGap(11) 
        .addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 
        .addContainerGap(12, Short.MAX_VALUE)) 
     ); 
     gl_panel.setVerticalGroup(
      gl_panel.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_panel.createSequentialGroup() 
        .addGap(5) 
        .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE) 
        .addContainerGap()) 
     ); 
     panel.setLayout(gl_panel); 
     contentPane.setLayout(gl_contentPane); 



    } 

    private void initColumnSizes(JTable table) { 
     MyTableModel model = (MyTableModel)table.getModel(); 
     TableColumn column = null; 
     Component comp = null; 
     int headerWidth = 0; 
     int cellWidth = 0; 
     Object[] longValues = model.longValues; 
     TableCellRenderer headerRenderer = 
      table.getTableHeader().getDefaultRenderer(); 

     for (int i = 0; i < 2; i++) { 
      column = table.getColumnModel().getColumn(i); 

      comp = headerRenderer.getTableCellRendererComponent(
           null, column.getHeaderValue(), 
           false, false, 0, 0); 
      headerWidth = comp.getPreferredSize().width; 

      comp = table.getDefaultRenderer(model.getColumnClass(i)). 
          getTableCellRendererComponent(
           table, longValues[i], 
           false, false, 0, i); 
      cellWidth = comp.getPreferredSize().width; 

      if (DEBUG) { 
       System.out.println("Initializing width of column " 
            + i + ". " 
            + "headerWidth = " + headerWidth 
            + "; cellWidth = " + cellWidth); 
      } 

      column.setPreferredWidth(Math.max(headerWidth, cellWidth)); 
     } 
    } 

    class MyEditor extends DefaultCellEditor { 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private JTextField textField; 
     private boolean valueSet; 
      public MyEditor() { 
      super(new JTextField()); 
      } 

      @Override 
      public boolean isCellEditable(EventObject eo) { 
       System.err.println("isCellEditable"); 
       if (eo instanceof KeyEvent) { 
        KeyEvent ke = (KeyEvent) eo; 
        System.err.println("key event: " + ke.getKeyChar()); 
        textField.setText(String.valueOf(ke.getKeyChar())); 
        //textField.select(1,1); 
        //textField.setCaretPosition(1); 
        //textField.moveCaretPosition(1); 
        valueSet = true; 
       } else { 
        valueSet = false; 
       } 
       return true; 
      } 
    } 





    class MyTableModel extends AbstractTableModel { 
     /** 
     * 
     */ 
     private static final long serialVersionUID = 1L; 
     private String[] columnNames = {"Nome Job", "Durata"}; 
     int numJob=DataJobManager.loadNumeroLavori(); 
     private Object[][] data = getDatiDefaultTabella(); 

     public class Job { 
      public int time; // Should n't this be a long? 
      public String jobName; 
     } 

     public Object[][] getDatiDefaultTabella(){ 
      Object[][] tabella=new Object[numJob][2]; 
      for(int i=0; i<numJob; i++){ 
       for(int j=0; j<2; j++){ 
        tabella[i][j]="inserisci dati"; 
       } 
      } 

      return tabella; 
     } 

     public Object[][] getTabella(){ 
      return data; 
     } 


     public int getColumnCount() { 
      return columnNames.length; 
     } 

     public int getRowCount() { 
      return numJob; 
     } 

     public String getColumnName(int col) { 
      return columnNames[col]; 
     } 

     public Object getValueAt(int row, int col) { 
      return data[row][col]; 
     } 

     /* 
     * JTable uses this method to determine the default renderer/ 
     * editor for each cell. If we didn't implement this method, 
     * then the last column would contain text ("true"/"false"), 
     * rather than a check box. 
     */ 
     public Class getRowClass(int r) { 
      return getValueAt(r, 0).getClass(); 
     } 

     public Class getColumnClass(int c) { 
      return getValueAt(0, c).getClass(); 
     } 


     /* 
     * Don't need to implement this method unless your table's 
     * editable. 
     */ 
     public boolean isCellEditable(int row, int col) { 
      //Note that the data/cell address is constant, 
      //no matter where the cell appears onscreen. 
      return true; 
     } 



     /* 
     * Don't need to implement this method unless your table's 
     * data can change. 
     */ 
     public void setValueAt(Object value, int row, int col) { 
      if (DEBUG) { 
       System.out.println("Setting value at " + row + "," + col 
            + " to " + value 
            + " (an instance of " 
            + value.getClass() + ")"); 
      } 

      data[row][col] = value; 
      fireTableCellUpdated(row, col); 

      if (DEBUG) { 
       System.out.println("New value of data:"); 
       printDebugData(); 
      } 
     } 

     private void printDebugData() { 
      int numRows = getRowCount(); 
      int numCols = getColumnCount(); 

      for (int i=0; i < numRows; i++) { 
       System.out.print(" row " + i + ":"); 
       for (int j=0; j < numCols; j++) { 
        System.out.print(" " + data[i][j]); 
       } 
       System.out.println(); 
      } 
      System.out.println("--------------------------"); 
     } 
    } 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 

     public void run() { 
      try { 
       CompileDataJob frame = new CompileDataJob(); 
       frame.setVisible(true); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
} 
+2

Dieser Code würde nicht kompilieren, so ist es schwer zu sehen, wie Sie es verwenden können. –

+0

Ich habe den gesamten Interface-Code bearbeitet und hinzugefügt ... also könntest du jetzt versuchen, ihn zu kompilieren, wenn du willst. 'DataJobManager' ist einfach eine Eingabe/Ausgabe Stream-Klasse, wo ich einige Daten speichern und laden, und Job ist ein einfaches Objekt mit' String ID, Int Zeit' – AndreaF

+0

@AndreaF wieder Ich löschte meine Antwort hier, vielleicht kann jemand Ihnen helfen ... – mKorbel

Antwort

1

Ok, ich denke, ich habe es. Ich habe deinen Code ein wenig optimiert und Sachen gelöscht, die ich nicht brauchte. Sie können es erneut hinzufügen. Hier

ist CompileDataJob

public class CompileDataJob extends JFrame { 
    final boolean DEBUG = false; 
    private final JPanel contentPane; 

    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        CompileDataJob frame = new CompileDataJob(); 
        frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the frame. 
    */ 
    public CompileDataJob() { 
     setTitle("Inserisci i parametri dei lavori"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setBounds(100, 100, 551, 293); 
     contentPane = new JPanel(); 
     contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 
     setContentPane(contentPane); 

     JPanel panel_1 = new JPanel(); 
     final JTable table = new JTable(new MyTableModel()); 

     JButton add = new JButton(" ADD "); 
     add.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
      ((MyTableModel)table.getModel()).addRow(new Job(0, "")); 
     } 
     }); 

     JButton btnNewButton = new JButton(" OK "); 
     btnNewButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       try{ 
         DataJobManager.saveListaLavori(((MyTableModel)table.getModel()).getJobs()); 
         CompileDataJob.this.dispose(); 
         JOptionPane.showMessageDialog(CompileDataJob.this,"Data Saved"); 
       }catch(Exception ecc){ 
        JOptionPane.showMessageDialog(CompileDataJob.this,"Error during the saving."); 
       } 
      } 
     }); 
     panel_1.add(btnNewButton); 
     panel_1.add(add); 
     JButton btnNewButton_1 = new JButton("Cancel"); 
     btnNewButton_1.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent arg0) { 
       CompileDataJob.this.dispose(); 
      } 
     }); 

     JPanel panel = new JPanel(); 



//  table.setDefaultEditor(Object.class,new MyEditor()); 

     table.setPreferredScrollableViewportSize(new Dimension(500, 70)); 
     table.setFillsViewportHeight(true); 

       //Create the scroll pane and add the table to it. 
       JScrollPane scrollPane = new JScrollPane(table); 


     panel_1.add(btnNewButton_1); 
     GroupLayout gl_contentPane = new GroupLayout(contentPane); 
     gl_contentPane.setHorizontalGroup(
      gl_contentPane.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_contentPane.createSequentialGroup() 
        .addGroup(gl_contentPane.createParallelGroup(Alignment.TRAILING, false) 
         .addComponent(panel_1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
         .addComponent(panel, GroupLayout.DEFAULT_SIZE, 525, Short.MAX_VALUE)) 
        .addContainerGap()) 
    ); 
     gl_contentPane.setVerticalGroup(
      gl_contentPane.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_contentPane.createSequentialGroup() 
        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 213, GroupLayout.PREFERRED_SIZE) 
        .addPreferredGap(ComponentPlacement.RELATED, 61, Short.MAX_VALUE) 
        .addComponent(panel_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) 
    ); 
     GroupLayout gl_panel = new GroupLayout(panel); 
     gl_panel.setHorizontalGroup(
      gl_panel.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_panel.createSequentialGroup() 
        .addGap(11) 
        .addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 
        .addContainerGap(12, Short.MAX_VALUE)) 
    ); 
     gl_panel.setVerticalGroup(
      gl_panel.createParallelGroup(Alignment.LEADING) 
       .addGroup(gl_panel.createSequentialGroup() 
        .addGap(5) 
        .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE) 
        .addContainerGap()) 
    ); 
     panel.setLayout(gl_panel); 
     contentPane.setLayout(gl_contentPane); 



    } 
} 

Hier Job ist

public class Job { 
    public int time = 500; // Should n't this be a long? 
    public String jobName; 
    public boolean processed = false; 

    public Job(int time, String jobName) { 
     this.time = time; 
     this.jobName = jobName; 
    } 

    public boolean isProcessed() { 
     return processed; 
    } 
} 

Und hier ist Ihr Tablemodel, es optimierbar ist, aber funktioniert ...

class MyTableModel extends AbstractTableModel { 
    private static final long serialVersionUID = 1L; 
    private final List<Job> objects = new ArrayList<Job>(); 
    private final String[] columnNames = { "Nome Job", "Durata", "processed" }; 

    private final Class<?>[] metaModell = new Class[]{String.class, Integer.class, Boolean.class}; 

    public int getColumnCount() { 
     return columnNames.length; 
    } 

    public int getRowCount() { 
     return objects.size(); 
    } 

    @Override 
    public String getColumnName(int col) { 
     return columnNames[col]; 
    } 

    public Object getValueAt(int row, int col) { 
     if (row >= objects.size()) 
      return null; 
     Job job = getRow(row); 
     switch (col) { 
      case 0: 
       return job.jobName; 
      case 1: 
       return job.time; 
      case 2: 
       return job.isProcessed(); 
     } 
     return null; 
    } 

    private Job getRow(int row) { 
     return objects.get(row); 
    } 

    @Override 
    public Class<?> getColumnClass(int c) { 
     if (c < metaModell.length) 
      return metaModell[c]; 
     return Object.class; 
    } 

    @Override 
    public boolean isCellEditable(int row, int col) { 
     return col >= 0 && col < columnNames.length; 
    } 

    @Override 
    public void setValueAt(Object value, int row, int col) { 
     Job job = getRow(row); 
     switch (col) { 
      case 0: 
       job.jobName = (String) value; 
       break; 
      case 1: 
       job.time = (Integer) value; 
       break; 
//   case 2: 
//    job.processed = (Boolean) value; 
//    break; 
     } 
     fireTableDataChanged(); 
    } 

    public List<Job> getJobs() { 
     return objects; 
    } 

    public void addRow(Job job) { 
     this.objects.add(job); 
     fireTableDataChanged(); 
    } 
} 

Wie du willst Ich habe alle MyEditor-Sachen und die komplizierten getValues ​​aus dem Editor-Zeug gelöscht. Stattdessen fügte ich dem Tabellenmodell eine Methode addJob() und getJobs hinzu.

+0

zu speichern gab es einen kleinen Fehler, funktioniert aber gut ... Vielen Dank! – AndreaF

0

Okay, Ihre Klasse eine CellEditor definieren, aber es tut nichts der DefaultEditor würde nicht tun.

Zusätzlich kleben Sie es nicht zusammen. Ihre JTable weiß nicht, welchen CellEditor sie verwenden soll. Sie müssen Ihre Tabelle anweisen, Ihre Implementierung des Editors zu verwenden. Es gibt mehrere Möglichkeiten, dies zu tun (z. B. um einen Standard-Renderer für eine Klasse festzulegen, der von Ihrem TableModel zurückgegeben wird). Sie können auch eine CellEditor direkt an der Säule zuweisen ( column.setCellEditor(new MyCellEditor()); ->http://docs.oracle.com/javase/tutorial/uiswing/components/table.html)

+0

Ich weiß das ... aber das Problem ist, wie Sie den richtigen CellEditor implementieren, um die Lösung dieses Problems zu erfüllen. – AndreaF

+0

Ok Ich bin mir nicht sicher, ob ich dein Problem bekomme. Sie haben eine Tabelle mit zwei Spalten (1. Spalte ist eine Nummer -> Jobnummer, 2. Spalte ist ein String). Sie müssen also 2 Standard-Editoren für Integer.class und String.class einstellen. Object.class kann tun, was Sie wollen, aber Ihre Methoden get * Class() geben konkrete Klassen zurück, so dass auch der konkrete Editor verwendet wird (und soweit ich weiß, dass ein Standardeditor für String ebenfalls registriert ist) – zip

+0

Was ich wollte say is: teste 'table.setDefaultEditor (Integer.class, new MyEditor());' und 'table.setDefaultEditor (String.class, new MyEditor());' anstelle von 'table.setDefaultEditor (Object.class, new MyEditor()); ' – zip