为具有2列(字符串,整数)和n行的JTable实现自定义CellEditor [英] Implements a custom CellEditor for a JTable with 2 columns (String, Integer) and n Rows

查看:90
本文介绍了为具有2列(字符串,整数)和n行的JTable实现自定义CellEditor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含N行2列的JTable,我需要实现一个自定义的CellEditor类,以使用

I have a JTable with N rows and 2 columns I need to implement a custom CellEditor class to access the data input of each cell with

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

我已经使用了CellEditor类

I have used this CellEditor class

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

但是不足以访问正确的单元格位置中的数据...(而且似乎所有表都被视为一个完整的单元格

but is not enough to access the data in the right cell position... (and seems that all the table is seen as a whole cell)

我发现的所有示例都与使用单元格编辑器来阻止编辑单元格有关,如果输入不正确,但是任何明显的内容都可以帮助我解决问题.

all the example that I have found are relative to using cell editor to block the editing cell if the input is not correct but anything clear enough to help me to solve the problem.

PS 如果您想尝试详细了解整个界面(而非)如何工作,则整个代码是这样的:

PS If you want try to see in detail how the whole interface (not)works the whole code is this:

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

推荐答案

好的,我想我明白了. 我对代码进行了一些优化,并删除了不需要的内容.您可以再次添加它.

Ok, I guess I got it. I optimized your code a little and deleted stuff I didn't need. You may add it again.

这是CompileDataJob

Here is 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,可以优化,但是可以使用...

And here is Your TableModel, it is optimizable, but will work...

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.

As you will see I deleted all MyEditor stuff and the complicated getValues from editor stuff. I instead added a method addJob() and getJobs to the table model.

这篇关于为具有2列(字符串,整数)和n行的JTable实现自定义CellEditor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆