2015-02-15 1 views
1

Я вот уже пару лет здесь скрывался, и мне никогда не приходилось задавать вопрос, потому что я всегда находил свой ответ по чужому вопросу. Спасибо!JComboBox в ячейке JTable. Изменение выбора влияет на JComboBox в других строках.

Я предполагаю, что скрывающийся подошел к концу. Я видел подобные вопросы, но не совсем здесь: У меня есть 2 столбца JTable с JComboBox в первом столбце и целое число во втором столбце. JComboBox имеет ItemListener, настроенный таким образом, что, когда выбор в JComboBox изменяется, значение в столбце Integer устанавливается в выбранный comboBox индекс. Щелчок правой кнопкой мыши на таблице делает JPopupMenu с addRow() как MouseEvent.

Он отлично работает, пока я добавляю все строки, которые я хочу, при настройке DefaultTableModel. Но, если я запустил модель только с одной строкой и использовал MouseEvent (или любой другой способ добавления строк, кроме добавления их в параметры DefaultTableModel), чтобы добавить строки, когда мы начнем изменять выбор в списках, это изменит целочисленные значения в других строках.

Например, если я запустил программу и сразу добавлю две строки через MouseEvent, я затем выберите нуль из комбо в строке 0, один из комбо в строке 1 и два из комбо в строке 2. Все до сих пор ... Затем я возвращаюсь к строке 0, и как только я активирую combobox (я еще не выбрал элемент ...), он меняет целое число в строке 2 на 0. Может ли кто-нибудь сказать мне, как остановить целые числа меняются таким образом? здесь пробный код:

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ItemEvent; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JMenuItem; 
import javax.swing.JPopupMenu; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumnModel; 

public class JComboBoxInJTable { 

    public static void main(String[] args) { 
     new JComboBoxInJTable(); 
    } 

    public JComboBoxInJTable() { 
     EventQueue.invokeLater(() -> { 
      try { 
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       ex.printStackTrace(); 
      } 

      DefaultTableModel model = new DefaultTableModel(new Object[]{"ComboBox", "Index"}, 1); 
      JTable table = new JTable(model); 

      //popup menu to add row 
      JPopupMenu popup = new JPopupMenu(); 
      JMenuItem newRow; 
      newRow = new JMenuItem("New Row"); 
      newRow.setToolTipText("Add new row."); 
      newRow.addActionListener((ActionEvent nr) -> { 
       model.addRow(new Object[]{"", ""}); 
      }); 
      popup.add(newRow); 

      //set up right-click to open popup menu 
      table.addMouseListener(new MouseAdapter() { 
       @Override 
       public void mousePressed(MouseEvent rc) { 
        if (SwingUtilities.isRightMouseButton(rc)) { 
         if (table.getSelectedRow() >= 0) { 
          popup.show(table, rc.getX(), rc.getY()); 
         } 
        } 
       } 
      }); 

      JComboBox combo = new JComboBox(new Object[]{"Zero", "One", "Two", "Three"}); 
      combo.addItemListener((ItemEvent e) -> { 
       if (e.getStateChange() == ItemEvent.SELECTED) { 
        //sets value of cell to left of combobox to comboboxe's selected index 
        table.setValueAt(combo.getSelectedIndex(), table.getSelectedRow(), 1); 
       } else { 
        //do nothing... 
       } 
      }); 

      DefaultCellEditor comboEditor = new DefaultCellEditor(combo); 

      TableColumnModel tcm = table.getColumnModel(); 
      tcm.getColumn(0).setCellEditor(comboEditor); 

      JFrame frame = new JFrame("Testing"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(new JScrollPane(table)); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     }); 
    } 
} 

Как обычно, я уверен, что это что-то простое, что мне не хватает. Еще раз спасибо за помощь в прошлом и в будущем!

+0

Там должно быть необходимо для выпадающего списка, чтобы изменить данные, пусть модель сделать это – MadProgrammer

+0

Не вы используете 'MouseListener', чтобы показать всплывающие окна, различные ОС имеют разные триггеры для всплывающих окон, вместо этого используйте 'JTable.setComponentPopupMenu' – MadProgrammer

+0

. Что« кажется »происходит, когда вы меняете выделение, до того, как выбор действительно установлен,« JComboBox »обновляется текущим значением ячейки, это запускает и обновляет и обновляет ранее выбранную строку ... – MadProgrammer

ответ

1
  • Не используйте MouseListener с, чтобы показать всплывающее меню, различные операционные системы имеют различные триггеры для всплывающих окон, и не все они вызваны mousePressed. Вместо этого используйте JComponent#setComponentPopupMenu и дайте API взаимодействовать с ним.
  • Не изменяйте состояние модели из редактора. Это может привести к тому, что модель станет недействительной и вызовет другие побочные эффекты, как сейчас. Как только, кажется, происходит, когда выбрана новая строка, редактор обновляется значением ячейки строк, но выбор строки не задан, поэтому таблица по-прежнему считает, что предыдущая строка все еще выбрана. Вместо этого используйте методы setValueAt, чтобы принимать решения о том, что делать после изменения значения первых столбцов.

Например ...

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import javax.swing.DefaultCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JMenuItem; 
import javax.swing.JPopupMenu; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableColumnModel; 

public class JComboBoxInJTable { 

    public static void main(String[] args) { 
     new JComboBoxInJTable(); 
    } 

    private List<String> comboData; 

    public JComboBoxInJTable() { 
     EventQueue.invokeLater(() -> { 
      try { 
       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       ex.printStackTrace(); 
      } 

      DefaultTableModel model = new DefaultTableModel(new Object[]{"ComboBox", "Index"}, 1) { 

       @Override 
       public void setValueAt(Object aValue, int row, int column) { 
        super.setValueAt(aValue, row, column); 
        if (column == 0) { 
         String value = aValue == null ? null : aValue.toString(); 
         if (aValue == null) { 
          super.setValueAt(null, row, 1); 
         } else { 
          super.setValueAt(comboData.indexOf(aValue), row, 1); 
         } 
        } 
       } 

      }; 
      JTable table = new JTable(model); 
      table.setFillsViewportHeight(true); 
      table.setGridColor(Color.GRAY); 

      //popup menu to add row 
      JPopupMenu popup = new JPopupMenu(); 
      JMenuItem newRow; 
      newRow = new JMenuItem("New Row"); 
      newRow.setToolTipText("Add new row."); 
      newRow.addActionListener((ActionEvent nr) -> { 
       model.addRow(new Object[]{"", ""}); 
      }); 
      popup.add(newRow); 

      table.setComponentPopupMenu(popup); 

      comboData = new ArrayList<>(Arrays.asList(new String[]{"Zero", "One", "Two", "Three"})); 

      JComboBox combo = new JComboBox(comboData.toArray(new String[comboData.size()])); 
//   combo.addItemListener((ItemEvent e) -> { 
//    if (e.getStateChange() == ItemEvent.SELECTED) { 
//     //sets value of cell to left of combobox to comboboxe's selected index 
//     System.out.println("Selected row = " + table.getSelectedRow()); 
//     table.setValueAt(combo.getSelectedIndex(), table.getSelectedRow(), 1); 
//    } else { 
//     //do nothing... 
//    } 
//   }); 

      DefaultCellEditor comboEditor = new DefaultCellEditor(combo); 

      TableColumnModel tcm = table.getColumnModel(); 
      tcm.getColumn(0).setCellEditor(comboEditor); 

      JFrame frame = new JFrame("Testing"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(new JScrollPane(table)); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     }); 
    } 
} 
+0

Я использовал ваш пример в своем полном коде, и теперь он работает правильно. Не могу поверить, что я внес изменения в JTable, а не в TableModel. Я должен был знать лучше. Спасибо за отзыв о MouseListener на JPopupMenu, он работает так, как ожидалось. Я ценю ваше время и всех остальных, кто здесь тоже помогает! – koncentrik

Смежные вопросы