Использование всего (jComboBox, JTextField, jFileChooser) в качестве редактора таблиц отменяет ссылки

В приведенном ниже коде для различных строк одной и той же таблицы я пытаюсь установитьEditable comboBox в качестве редактора для первой строки (так что пользователь может выбирать из доступных вариантов или вводить свой собственный), выборщик файлов для второй строки и textFiled по умолчанию для остальных строк.

Problem: и шаги по его воспроизведению:

1- Запустите код, 2- нажмите на второй ряд и выберите папку (строка становится желтой) 3- Теперь нажмите на первую строку, чтобы выбрать тип фильма (просто нажмите, не нужно ничего вводить или выбирать) 4- Теперь сделайте еще один клик на второй ряд (выбор папки)

вы увидите, что содержимое этой строки будет скопировано в первую строку ?!

Я знаю, что есть много вещей, которые я не сделал правильно, возможно, обработка свингов, которые не являются поточно-ориентированными, обработка ссылок и так далее. Мне было интересно, если вы, ребята, можете помочь мне исправить эту ошибку и превратить этот код во что-то солидное.

Program output before user makes selections

после следующих шагов выше:

enter image description here

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.table.TableModel;

public class CCellEditor extends DefaultCellEditor {

    private JTable m_Table = null;

    public CCellEditor(JFrame parentFrame, JTable table) { 
        super(new JTextField());
        super.setClickCountToStart(1);
        m_Table = table;
    }
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, int column){

        if(row==0) // comBoBox for First row
        {
            Object[] objectArray = {"3D","2D"};
            JComboBox comboBox = new JComboBox(objectArray);
            comboBox.setEditable(true);
            comboBox.setSelectedItem(value);

            ItemListener itemListener = new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    if(e.getStateChange() == ItemEvent.SELECTED) {
                        if(null != m_Table.getCellEditor()){ 
                            m_Table.getCellEditor().stopCellEditing();
                        }

                        m_Table.setValueAt(e.getItem(), row, 1);
                    }
                }
            };
            comboBox.addItemListener(itemListener);

            PopupMenuListener popMenuEvent = new PopupMenuListener() {

                public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                }

                public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                    String sValue = (String)m_Table.getValueAt(row, 1);
                    if(null != m_Table.getCellEditor()){ 
                        m_Table.getCellEditor().stopCellEditing();
                    }
                    m_Table.setValueAt(sValue, row, 1);
                }

                public void popupMenuCanceled(PopupMenuEvent e) {   
                }

            };
            comboBox.addPopupMenuListener(popMenuEvent);

            return comboBox;

        }

        else  if(row==1)  // fileChooser for Second row
        {
            JFileChooser fileChooser;
            fileChooser = new JFileChooser("c:\\");
            fileChooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
            fileChooser.setVisible(true);
            int returnVal = fileChooser.showOpenDialog(null);

            JTextField textField = (JTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
            textField.setBackground(Color.yellow);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File m_fFirmware= fileChooser.getSelectedFile();

                textField.setText(m_fFirmware.getPath());
                return textField;

            }else
            {
                return textField; 

            }
        }
                                // for any other rows
        JTextField textField = (JTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column);
        return textField;

    }

    public static void main(String[] a) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        String[] columnTitles = { "Name", "Value"};
        Object[][] dataEntries = {
                { "Movie Type:", "3D" }, {"Folder:","C:"}, {"# of Movies requested:","5"}};
        TableModel model = new EditableTableModel(columnTitles, dataEntries);
        JTable table = new JTable(model);
        table.createDefaultColumnsFromModel();
        table.setDefaultEditor(Object.class, new CCellEditor(frame, table));
        frame.add(new JScrollPane(table));
        frame.setSize(300, 200);
        frame.setVisible(true);
    }

}

и вот класс EditableTableModel:

import javax.swing.table.AbstractTableModel;


class EditableTableModel extends AbstractTableModel {
  String[] columnTitles;

  Object[][] dataEntries;

  int rowCount;

  public EditableTableModel(String[] columnTitles, Object[][] dataEntries) {
    this.columnTitles = columnTitles;
    this.dataEntries = dataEntries;
  }

  public int getRowCount() {
    return dataEntries.length;
  }

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

  public Object getValueAt(int row, int column) {
    return dataEntries[row][column];
  }

  public String getColumnName(int column) {
    return columnTitles[column];
  }

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

  public boolean isCellEditable(int row, int column) {
    return true;
  }

  public void setValueAt(Object value, int row, int column) {
    dataEntries[row][column] = value;
  }



}
 C graphics15 июн. 2012 г., 00:26
@Max Спасибо за ваше внимание, я только что добавил класс EditableTableModel в код выше.
 tenorsax15 июн. 2012 г., 00:20
Что такоеEditableTableModel?

Ответы на вопрос(2)

Решение Вопроса

что это заняло у меня некоторое время, но я нашел проблему. Вы не изменилиDefaultCellEditor.getCellEditorValue() функция, которая важна для вашей реализации. Эта функция вызывается, когда редактируемая ячейка теряет фокус или что-либо еще заставляет редактирование завершиться. В любом случае, в вашем случае, он просто получает окончательное значение из последнего TableCellEditor по умолчанию (из DefaultCellEditor). Вот почему первая строка продолжает заменяться на последнее отредактированное значение ячейки.

Вот способ решить вашу проблему:

Create a global reference to the comboBox. Override getCellEditorValue() and return comboBox.getSelectedItem() if the last edited item was the second row. Otherwise, just return super.getCellEditorValue().

Это исправит вашу текущую проблему, но ваш код может быть значительно улучшен.

 15 июн. 2012 г., 07:06
+1 для выделенияgetCellEditorValue(), который я отправил в комментарий.DefaultCellEditor У выпадающего списка есть рабочая реализация.
 C graphics15 июн. 2012 г., 20:20
Это было совершенно правильно. Я переопределил getCellEditorValue (), и он начал работать без проблем. Спасибо.
 16 июн. 2012 г., 17:42
+1 за поиск getCellEditorValue ()

об изменении:

public void setValueAt(Object value, int row, int column) {
    dataEntries[row][column] = value;
    fireTableCellUpdated(row, column);
}

Смотрите такжеInitial Threadsи рассмотрим один из этих каталогов по умолчанию.

fileChooser = new JFileChooser(System.getProperty("user.dir"));
fileChooser = new JFileChooser(System.getProperty("user.home"));
 16 июн. 2012 г., 17:43
отличные предложения +1
 C graphics15 июн. 2012 г., 02:28
Спасибо за ваши советы, пока не повезло. Эта проблема с Cell-Editing беспокоит меня плохо
 15 июн. 2012 г., 02:17
Смотрите также это связаноexample; переопределениеgetCellEditorValue() может упростить вашу реализацию.
 15 июн. 2012 г., 02:36
Начните с исправления комбинированного редактора, чтобы он соответствовал учебнику; затем используйте другой редактор для выбора. Не пытайтесь иметь один редактор для обработки всех типов объектов.

Ваш ответ на вопрос