2012-06-02 3 views
2

Я пытаюсь связать ComboBoxes. Например, у меня есть три сборника, и каждый из них имеет три элемента (a, b, c). В начале в первом поле со списком «а» выбирается во втором «b» и «c» в третьем. Мне нужно сделать для них ActionListener, который работает следующим образом: если выбор изменения во втором списке от «b» до «a», в первом списке выбранный элемент автоматически изменяется с «a» на «b».Связанные ComboBoxes

Я попытался решить эту проблему таким образом:

public class MyComboBoxListener implements ActionListener { 

     public void actionPerformed(ActionEvent a) { 
      int i = 0; 
      int j = 0; 
      while (a.getSource() != valsListArray.get(i)) { 
       i++; 
      } 
      String selected = valsListArray.get(i).getSelectedItem().toString(); 
      while (selected != valsListArray.get(j).getSelectedItem() && j != i) { 
       j++; 
      } 
      String r = chosenVals[i];// in the beginnig elements are that order a, b, c 
      valsListArray.get(j).setSelectedItem(chosenVals[i]); 
      chosenVals[j] = r; 
      chosenVals[i] = selected; 
     } 
    } 

, но это не решает проблему.

+0

Это похоже на необычный и необычный пользовательский компонент - вполне возможно, непригодным для использования. Кажется, что «JList» с Drag'n'Drop может быть лучшим способом. Что такое b & c? В чем смысл «взаимоисключающих» комбо? –

ответ

6

Yours интересная проблема. Одним из решений является расширение JComboBox таким образом, что оно будет содержать ссылку на ранее выбранный элемент и индекс, и это позволит вам извлекать информацию по мере необходимости. Например:

import javax.swing.ComboBoxModel; 
import javax.swing.JComboBox; 

public class NewComboBox extends JComboBox { 
    private Object previousSelectedItem = null; 
    private int previousSelectedIndex = -1; 

    public Object getPreviousSelectedItem() { 
     return previousSelectedItem; 
    } 

    public int getPreviousSelectedIndex() { 
     return previousSelectedIndex; 
    } 

    NewComboBox(ComboBoxModel aModel) { 
     super(aModel); 
    } 

    @Override 
    public void setSelectedIndex(int anIndex) { 
     previousSelectedIndex = getSelectedIndex(); 
     previousSelectedItem = getSelectedItem(); 
     super.setSelectedIndex(anIndex); 
    } 

    @Override 
    public void setSelectedItem(Object anObject) { 
     previousSelectedIndex = getSelectedIndex(); 
     previousSelectedItem = getSelectedItem(); 
     super.setSelectedItem(anObject); 
    } 

} 

И тогда вы можете использовать его по мере необходимости. Например,

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class LinkedCombos extends JPanel { 
    public static final String[] DATA = {"a", "b", "c"}; 
    public static final int COMBO_COUNT = 3; 
    private DefaultComboBoxModel[] comboModels = new DefaultComboBoxModel[COMBO_COUNT]; 
    private NewComboBox[] comboBoxes = new NewComboBox[COMBO_COUNT]; 
    private MyComboListener myComboListener = new MyComboListener(); 

    public LinkedCombos() { 
     for (int i = 0; i < comboModels.length; i++) { 
     comboModels[i] = new DefaultComboBoxModel(DATA); 
     comboBoxes[i] = new NewComboBox(comboModels[i]); 
     comboBoxes[i].setSelectedIndex(i); 
     comboBoxes[i].addActionListener(myComboListener); 
     add(comboBoxes[i]); 
     } 
    } 

    private class MyComboListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent evt) { 
     NewComboBox combo = (NewComboBox) evt.getSource(); 
     String selection = combo.getSelectedItem().toString(); 

     for (int i = 0; i < comboBoxes.length; i++) { 
      NewComboBox comboI = comboBoxes[i]; 
      if (comboI != combo && comboI.getSelectedItem().equals(selection)) { 
       comboI.setSelectedItem(combo.getPreviousSelectedItem()); 
      } 
     } 
     } 
    } 

    private static void createAndShowGui() { 
     LinkedCombos mainPanel = new LinkedCombos(); 

     JFrame frame = new JFrame("LinkedCombos"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+0

согласился с вашим комментарием в ответе, EDIT ..., интересный код +100 – mKorbel

+0

Большое спасибо. Это именно то, что я имел в виду. –

6

, например (только два связанных JComboBoxes, остальное/до вас, я удаленный код 3. JComboBox намеренно)

import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 

public class ComboBoxTwo extends JFrame implements ActionListener, ItemListener { 

    private static final long serialVersionUID = 1L; 
    private JComboBox mainComboBox; 
    private JComboBox subComboBox; 
    private Hashtable<Object, Object> subItems = new Hashtable<Object, Object>(); 

    public ComboBoxTwo() { 
     String[] items = {"Select Item", "Color", "Shape", "Fruit"}; 
     mainComboBox = new JComboBox(items); 
     mainComboBox.addActionListener(this); 
     mainComboBox.addItemListener(this); 
     //prevent action events from being fired when the up/down arrow keys are used 
     //mainComboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); 
     getContentPane().add(mainComboBox, BorderLayout.WEST); 
     subComboBox = new JComboBox();// Create sub combo box with multiple models 
     subComboBox.setPrototypeDisplayValue("XXXXXXXXXX"); // JDK1.4 
     subComboBox.addItemListener(this); 
     getContentPane().add(subComboBox, BorderLayout.EAST); 
     String[] subItems1 = {"Select Color", "Red", "Blue", "Green"}; 
     subItems.put(items[1], subItems1); 
     String[] subItems2 = {"Select Shape", "Circle", "Square", "Triangle"}; 
     subItems.put(items[2], subItems2); 
     String[] subItems3 = {"Select Fruit", "Apple", "Orange", "Banana"}; 
     subItems.put(items[3], subItems3); 
//  mainComboBox.setSelectedIndex(1); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     String item = (String) mainComboBox.getSelectedItem(); 
     Object o = subItems.get(item); 
     if (o == null) { 
      subComboBox.setModel(new DefaultComboBoxModel()); 
     } else { 
      subComboBox.setModel(new DefaultComboBoxModel((String[]) o)); 
     } 
    } 

    @Override 
    public void itemStateChanged(ItemEvent e) { 
     if (e.getStateChange() == ItemEvent.SELECTED) { 
      if (e.getSource() == mainComboBox) { 
       if (mainComboBox.getSelectedIndex() != 0) { 
        FirstDialog firstDialog = new FirstDialog(ComboBoxTwo.this, 
          mainComboBox.getSelectedItem().toString(), "Please wait, Searching for ..... "); 
       } 
      } 
     } 
    } 

    private class FirstDialog extends JDialog { 

     private static final long serialVersionUID = 1L; 

     FirstDialog(final Frame parent, String winTitle, String msgString) { 
      super(parent, winTitle); 
      setModalityType(Dialog.ModalityType.APPLICATION_MODAL); 
      JLabel myLabel = new JLabel(msgString); 
      JButton bNext = new JButton("Stop Processes"); 
      add(myLabel, BorderLayout.CENTER); 
      add(bNext, BorderLayout.SOUTH); 
      bNext.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent evt) { 
        setVisible(false); 
       } 
      }); 
      javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        setVisible(false); 
       } 
      }); 
      t.setRepeats(false); 
      t.start(); 
      setLocationRelativeTo(parent); 
      setSize(new Dimension(400, 100)); 
      setVisible(true); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new ComboBoxTwo(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

+1 для моделирования латентности. – trashgod

+0

Я имел в виду еще одну проблему, но, спасибо, мне все же полезно. –