0

N 行 2 列の JTable があります。各セルのデータ入力にアクセスするには、カスタム CellEditor クラスを実装する必要があります。

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

この CellEditor クラスを使用しました

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

しかし、正しいセル位置のデータにアクセスするには十分ではありません...(そして、すべてのテーブルがセル全体として見られているようです)

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

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

2 に答える 2

1

わかりました、私はそれを手に入れたと思います。コードを少し最適化し、不要なものを削除しました。再度追加できます。

これが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テーブルモデルを追加しました。

于 2012-04-10T14:38:50.367 に答える
0

あなたのクラスは CellEditor を定義しますが、DefaultEditor がしないことは何もしません。

また、接着はしません。JTable は、どの CellEditor を使用すべきかを知りません。エディターの実装を使用するようにテーブルに指示する必要があります。これを行うには複数の方法があります (たとえば、テーブルモデルによって返されるクラスのデフォルト レンダラーを設定するなど)。CellEditor を列に直接割り当てることもできます ( column.setCellEditor(new MyCellEditor());--> http://docs.oracle.com/javase/tutorial/uiswing/components/table.html )

于 2012-04-09T18:19:07.780 に答える