2012-04-09 2 views
0

N行2列のJTableを持っています。各セルのデータ入力にアクセスするためにカスタムCellEditorクラスを実装する必要があります。2列(String、Integer)とn行のJTableのカスタムCellEditorを実装します。

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

私は

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

このcellEditorをクラスを使用しますが...右のセルの位置にあるデータにアクセスするだけでは十分ではない(と、すべてのテーブルは全細胞として見られているようだ)しています

私が見つけたすべての例は、入力が正しくない場合でも編集セルをブロックするためにセルエディタを使用することに関連していますが、問題を解決するのに役立つほど明確なものはありません。

PS あなたは全体のインターフェイスは(ない)全体のコードをどのように動作するかを詳細に見てみたい場合はこれです:

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

そのコードはコンパイルされないので、どのように使用できるか分かりません。 –

+0

私はインターフェイスコード全体を編集して追加しました...だから、必要ならばコンパイルを試みることができます。 'DataJobManager'は単にデータを保存して読み込む入出力のストリームクラスです。ジョブは' String id、int time'の単純オブジェクトです – AndreaF

+0

@AndreaFもう一度私の答えを削除しました。 ... – mKorbel

答えて

1

- また、カラム(>http://docs.oracle.com/javase/tutorial/uiswing/components/table.html column.setCellEditor(new MyCellEditor());)に直接cellEditorを割り当てることができます。 あなたのコードを少し最適化し、私が必要としなかったものを削除しました。もう一度追加することができます。ここで

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



    } 
} 

ここで仕事

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

そして、ここであなたのTableModelがあるが、それは最適化可能ですが、動作します...

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

必要になりますようです私がMyEditorのすべてのものと複雑なgetValuesをエディタのものから削除したのを見てください。代わりに、addJob()getJobsというメソッドをテーブルモデルに追加しました。

+0

少しエラーがありましたが、うまくいきます...ありがとう! – AndreaF

0

オーケー、あなたのクラスがcellEditorをを定義しませんが、それは何もしません。 DefaultEditorは実行しません。

さらに、あなたはそれを一緒に接着しません。 JTableは、使用するCellEditorを認識していません。 エディタの実装を使用するようにテーブルに指示する必要があります。 これには複数の方法があります(たとえば、テーブルモデルによって返されるクラスのデフォルトのレンダラーを設定するなど)。 [OK]を、私はそれを得たと思い

+0

私はこれを知っています...しかし、問題は、この問題の解決策を満たすために正しいcellEditorを実装する方法です。 – AndreaF

+0

オクラホマ問題があるかどうかは分かりません。 2つの列を持つ表があります(1.列は数値 - >ジョブ番号、2列はストリングです)。したがって、Integer.classとString.classには2つのデフォルトエディタを設定する必要があります。 Object.classはあなたが望むことを行うことができますが、get * Class()メソッドは具体的なクラスを返すので、具体的なエディタも使用されます(そして、Stringのデフォルトエディタも登録されていることがわかります) – zip

+0

次のように言ってください: 'table.setDefaultEditor(Object.class、new MyEditor(new MyEditor());)の代わりに' 'table.setDefaultEditor(Integer.class、new MyEditor());' 'と' 'table.setDefaultEditor(String.class、new MyEditor()); ()); – zip

関連する問題