2013-07-26 3 views
0

JComboBox에 파일 정보 (XML)가 채워져 있고 두 번째 ComboBox에 첫 번째 항목의 선택한 항목에 기반한 정보가 입력되기를 원합니다.연관 배열을 사용하지 않고 JComboBox를 동적으로 채우기

<components> 
    <house id="Kitchen"> 
     <espresso_machine>C</espresso_machine> 
     <coffee_machine>C</coffee_machine> 
     <coffee_pot>C</coffee_pot> 
     <kettle>C</kettle> 
     <toaster>C</toaster> 
     <microwave>C</microwave> 
     <oven>C</oven> 
     <frying_pan>C</frying_pan> 
     <stand_mixer>C</stand_mixer> 
     <extrator_fan>C</extrator_fan> 
     <tv>C</tv> 
     <compact_flurescent>C</compact_flurescent> 
     <flurescent_tube>C</flurescent_tube> 
     <dishwasher>C</dishwasher> 
     <freezer>C</freezer> 
     <blender>C</blender> 
     <can_opener>C</can_opener> 
     <cooking_range>C</cooking_range> 
     <popcorn_popper>C</popcorn_popper> 
    </house> 
    <house id="Laundry"> 
     <washing_machine>C</washing_machine> 
     <clothes_dryer>C</clothes_dryer> 
     <vacuum_handler>C</vacuum_handler> 
     <compact_fluorescent>C</compact_fluorescent> 
     <iron>C</iron> 
    </house> 
    <house id="Room"> 
     <compact_fluorescent>C</compact_fluorescent> 
     <ac_room>C</ac_room> 
     <tv>C</tv> 
     <cell_phone_charger>C</cell_phone_charger> 
     <clock_radio>C</clock_radio> 
    </house> 
</components> 

나의 첫 번째 콤보 상자가 속성 "ID"컨텐츠 (주방, 세탁, 룸)가 있습니다

내 영어는 내가 당신에게 예를 보여 드리겠습니다 때문에 약간 녹슨이 내 XML 파일입니다. JDialog를 처음 열면 첫 번째 콤보 상자에서 "주방"옵션이 선택되고 두 번째 콤보 상자에는 모든 하위 요소가 정규화 된 이름 (에스코 기계, 커피 머신, 커피 포트, 커피 포트, 주전자 등)이 있습니다.

첫 번째 항목에서 선택한 항목을 변경할 때 두 번째 콤보 상자의 내용이 변경되어야합니다.

houseSpaceCombo = new JComboBox(configs.XMLreaderDOM4J.readHouseTypeID()); 
equipmentsCombo = new JComboBox(configs.XMLreaderDOM4J.readHouseEquipmentsID(houseSpaceCombo.getSelectedItem().toString())); 

다른 두 가지 방법 :

public static String[] readHouseTypeID() 
{  
    Element root = getDoc().getRootElement(); 

    ArrayList<String> attributeAL = new ArrayList<>(); 

    for (Iterator i = root.elementIterator("house"); i.hasNext();) 
    { 
     Element foo = (Element) i.next(); 
     attributeAL.add(foo.attributeValue("id").toString()); 
    } 

    String[] vec = convertArrayListToArray(attributeAL); 

    return vec; 
} 

public static String[] readHouseEquipmentsID(String selectedItem) 
{  
    Element root = getDoc().getRootElement(); 
    Element innerElement; 

    ArrayList<String> attributeAL = new ArrayList<>(); 

    for (Iterator i = root.elementIterator("house"); i.hasNext();) { 
    Element element = (Element) i.next(); 
    if(element.attributeValue("id").equals(selectedItem)) { 
     for (Iterator j = element.elementIterator(); j.hasNext();) { 
      innerElement = (Element) j.next(); 
      String tmp = innerElement.getQualifiedName().replace("_", " "); 

      attributeAL.add(tmp); 

     }  
    } 
} 

String[] vec = convertArrayListToArray(attributeAL); 

    return vec; 
} 

내가 무엇을 할 수

여기 내 코드의 샘플입니까?

답변

2

모든 하위 요소가 ComboBoxModelid 특성을 사용하여 Map을 생성했습니다.

첫 번째 콤보 상자 변경의 선택 항목을, 나는 간단한

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.HashMap; 
import java.util.Map; 
import javax.swing.ComboBoxModel; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class SwitchComboBoxModels { 

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

    public SwitchComboBoxModels() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Map<String, ComboBoxModel> models; 
     private JComboBox cbMain; 
     private JComboBox cbSub; 

     public TestPane() { 
      models = new HashMap<>(25); 
      models.put("Kitchen", createComboBoxModel("espresso_machine", 
        "coffee_machine", 
        "coffee_pot", 
        "kettle", 
        "toaster", 
        "microwave", 
        "oven", 
        "frying_pan", 
        "stand_mixer", 
        "extrator_fan", 
        "tv", 
        "compact_flurescent", 
        "flurescent_tube", 
        "dishwasher", 
        "freezer", 
        "blender", 
        "can_opener", 
        "cooking_range", 
        "popcorn_popper")); 
      models.put("Laundry", createComboBoxModel("washing_machine", 
        "clothes_dryer", 
        "vacuum_handler", 
        "compact_fluorescent", 
        "iron")); 

      ComboBoxModel mainModel = createComboBoxModel("Kitchen", "Laundry"); 

      cbMain = new JComboBox(); 
      cbSub = new JComboBox(); 
      cbMain.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        cbSub.setModel(models.get((String) cbMain.getSelectedItem())); 
       } 
      }); 
      cbMain.setModel(mainModel); 
      cbSub.setModel(models.get((String) cbMain.getSelectedItem())); 

      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      add(cbMain, gbc); 
      add(cbSub, gbc); 

     } 

     protected ComboBoxModel createComboBoxModel(String... values) { 

      return new DefaultComboBoxModel(values); 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.dispose(); 
     } 
    } 
} 

예를 Map의 값을 검색하고 검색된 값

에 두 번째 콤보 상자의 모델을 설정합니다 때 추가 예제

예제 코드에서 이미 모델을 메모리에 가지고 있습니다. 이 단계에서는 두 가지 선택 사항이 있습니다.

메모리 문서를 구문 분석하여 일련의 ComboBoxModel을 만들거나 변경 될 때마다 XML에서 모델을 차 동적으로 빌드 할 수 있습니다.

내가 XML DOM의 같은 결과를 시작할 때 모델을 구문 분석 및 캐싱에 가고 싶어

가 작동 할 수 있습니다 메모리 hungery

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.IOException; 
import java.util.Map; 
import javax.swing.ComboBoxModel; 
import javax.swing.DefaultComboBoxModel; 
import javax.swing.JComboBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathExpression; 
import javax.xml.xpath.XPathExpressionException; 
import javax.xml.xpath.XPathFactory; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 
import org.xml.sax.SAXException; 

public class SwitchComboBoxModels { 

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

    public SwitchComboBoxModels() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Document xmlDoc; 
     private JComboBox cbMain; 
     private JComboBox cbSub; 
     private XPathFactory xFactory; 
     private XPath xPath; 

     public TestPane() { 

      try { 

       readModel(); 
       ComboBoxModel mainModel = createComboBoxModelByID(find("/components/house[@id]")); 

       cbMain = new JComboBox(); 
       cbSub = new JComboBox(); 
       cbMain.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         updateSubModel(); 
        } 
       }); 
       cbMain.setModel(mainModel); 
       updateSubModel(); 

       setLayout(new GridBagLayout()); 
       GridBagConstraints gbc = new GridBagConstraints(); 
       gbc.gridwidth = GridBagConstraints.REMAINDER; 
       add(cbMain, gbc); 
       add(cbSub, gbc); 

      } catch (XPathExpressionException | ParserConfigurationException | SAXException | IOException exp) { 
       exp.printStackTrace(); 
      } 

     } 

     protected void updateSubModel() { 
      try { 
       String key = (String) cbMain.getSelectedItem(); 
       Node parent = findFirst("/components/house[@id='" + key + "']"); 
       ComboBoxModel subModel = createComboBoxModel(parent.getChildNodes()); 
       cbSub.setModel(subModel); 
      } catch (XPathExpressionException exp) { 
       exp.printStackTrace(); 
      } 
     } 

     protected void readModel() throws ParserConfigurationException, SAXException, IOException { 
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
      xmlDoc = factory.newDocumentBuilder().parse(getClass().getResourceAsStream("/Model.xml")); 
     } 

     protected NodeList find(String xPathQuery) throws XPathExpressionException { 
      XPathExpression xExpress = getXPath().compile(xPathQuery); 
      return (NodeList) xExpress.evaluate(xmlDoc.getDocumentElement(), XPathConstants.NODESET); 
     } 

     protected Node findFirst(String xPathQuery) throws XPathExpressionException { 
      XPathExpression xExpress = getXPath().compile(xPathQuery); 
      return (Node) xExpress.evaluate(xmlDoc.getDocumentElement(), XPathConstants.NODE); 
     } 

     public XPath getXPath() { 
      if (xPath == null) { 
       xPath = getXPathFactory().newXPath(); 
      } 
      return xPath; 
     } 

     protected XPathFactory getXPathFactory() { 

      if (xFactory == null) { 

       xFactory = XPathFactory.newInstance(); 

      } 

      return xFactory; 

     } 

     public String getAttributeValue(Node nNode, String sAttributeName) { 
      Node nAtt = nNode.getAttributes().getNamedItem(sAttributeName); 
      return nAtt == null ? null : nAtt.getNodeValue(); 
     } 

     protected ComboBoxModel createComboBoxModelByID(NodeList nodeList) { 

      DefaultComboBoxModel model = new DefaultComboBoxModel(); 
      for (int index = 0; index < nodeList.getLength(); index++) { 
       Node node = nodeList.item(index); 
       model.addElement(getAttributeValue(node, "id")); 
      } 

      return model; 

     } 

     protected ComboBoxModel createComboBoxModel(NodeList nodeList) { 

      DefaultComboBoxModel model = new DefaultComboBoxModel(); 
      for (int index = 0; index < nodeList.getLength(); index++) { 
       Node node = nodeList.item(index); 
       if (node.getNodeType() == 1) { 
        model.addElement(node.getNodeName()); 
       } 
      } 

      return model; 

     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.dispose(); 
     } 
    } 
} 
+0

는 내가 따를 수있는 코드 예제가 있나요, 입니까? – SaintLike

+0

감사합니다. 그다지 좋지는 않을 것입니다. 아주 좋은 아이디어입니다. 내 XML 파일이 너무 크고, 위에 게시 한 것은 샘플에 불과합니다. 어쨌든 고마워요. – SaintLike

+1

메모리를 사용하고 속도를 원하는 문제에 무게를 두어야 할 것입니다. 다른 선택은 기본 콤보 상자가 변경 될 때마다 XML 섹션을 읽는 것입니다. 메인 태그를 얻기 위해 이미 한 번에 파일을 읽었으므로 시간이 오래 걸립니다. 다시 읽어야하는 시간을 절약하기 위해 하위 요소를 캐시에 저장하고 싶을 것입니다 ... – MadProgrammer

관련 문제