2012-10-16 2 views
1

이 문제에 대한 해결책을 설계하는 데 어려움을 겪습니다. 경험이없는 부산물입니다.디자인 : 2 jcomboboxes, 상자 2 목록 상자 1의 선택에 따라 달라집니다. XML의 데이터

목표는 XML 입력 파일을 읽고 XML에서 정보를 저장하고 두 개의 콤보 상자에 XML 데이터를 채우는 것입니다. 두 번째 콤보 상자의 내용은 첫 번째 콤보 상자의 선택에 따라 변경됩니다.

이 XML 구조를 감안할 때 :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<Category xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<Node> 
    <ID>Unique string</ID> 
    <Name>Unique string</Name> 
    <Code>Generic string<Code> 
    <Kind>Generic string</Kind> 
    <Frame>Generic string</Frame> 
      ... 
</Node> 
    ... 
</Category> 

첫 번째 콤보 상자 : 은 종류 섹션에서 발견에만 고유 한 값을 포함해야합니다.

두 번째 콤보 상자 : 첫 번째 콤보 상자에서 Kind가 선택된 Kind와 동일한 모든 노드의 모든 Name 항목이 들어 있습니다.

XML 소스 관련 : 외부에서 유지 관리되고 생성됩니다. ID 섹션의 값은 항상 고유합니다. 이름 섹션의 값은 항상 고유합니다. 스키마가 변경되지 않습니다. 앞으로 새로운 고유 값이 종류 섹션에 나타날 수 있습니다.

제안 된 솔루션 : XML 원본에서 노드를 나타내는 XMLNode 클래스를 만듭니다. XMLNode 클래스의 멤버는 각 노드의 태그에 해당합니다. 모든 노드를 반복하고 각 노드마다 XMLNode를 만듭니다. 노드를 반복하면서 : 키 = XMLNode.ID 및 vals = XMLNode를 사용하여 XMLNode 객체를 해시 맵에 추가합니다. 고유 한 종류의 배열을 만듭니다.

종류 항목의 배열에서 콤보 상자 하나를 채 웁니다. 각각의 이름 데이터에서 콤보 상자 2를 채 웁니다.

이 방법이 적절한 방법입니까, 아니면 더 나은/더 쉽고/더 우아한 해결책을 간과 했습니까? 올바른 길을 가고 있다면 제안 된 솔루션에 명백한 결함이 있습니까? Runnable#Thread 또는 SwingWorker

  • -JComboBox

  • ll updates to the JComboBox and its ComboBoxModel must be done on EDT

  • 리디렉션 모든 FileIO 또는 Database 이벤트에 대한 저장 품목에 대한

  • +0

    두 번째 상자를 만들기위한 논리를 이해하는 데 도움 않습니다 아래 mKorbel의 제안 첫 번째 선택에 따라 달라 지므로 매우 유용합니다. 그러나 XML 데이터를 가져 와서 내 프로그램 내에서 표현하는 더 좋은 방법은 없습니다. 그 stackoverflow 하이브 마음에서 일부 의견은 인정 될 것입니다 ... – NickAbbey

    답변

    0

    . Node는 노드를 나타내고, NodeImporter는 XML을 구문 분석합니다. NodeImporter에서 XML 소스는 파싱되어 HashMap의 HashMap으로 표현됩니다. 바깥 쪽 HashMap (Key, Value)는 (Kind, (UniqueID, Node))의 최종 결과를위한 (UinqueID, Node) 내부 HashMap (Key, Value)입니다. 나는 최종 결과를 "filteredMap"이라고 부른다.NodeImporter의 모든 필드와 메소드는 private이며, 생성자는 제외하고 filteredMap의 getter입니다. 콤보 상자를 만들기 위해 데이터가 필요한 클래스는 NodeImporter 인스턴스에서 filteredMap을 가져옵니다. 그런 다음 외부 HashMap의 키를 가져 와서 첫 번째 ComboBoxModel을 빌드 할 수 있습니다. 내부 HashMap을 두 번째 콤보 상자의 HashMap으로 쉽게 사용할 수 있습니다. 설정을위한

    의사 코드 :

    클래스 NodeImporter 반원들과 함께 내장 :

    arrayList(String) uniqueKinds = null 
    arrayList(Node) allNodes = null 
    HashMap(String, HashMap(String,Node))) filteredNodes = null 
    

    클래스 NodeImporter 생성자 :

    open XML 
    while xml source has next 
        { 
        add next node to allNodes, key = node.uniqueId, Val = node 
        if next node.kind not in uniqueKinds, add node.kind to uniqueKinds 
        } 
    
    
    
    ClassNodeImporter method makeFilteredeMap: 
    
        private boolean makeFilteredeMap() { 
         if (uniqueKinds.isEmpty()) { 
          return false; 
         } else { 
          for (String k : uniqueKinds) { 
           HashMap<String, Node> aMap = new HashMap<String, Node>(); 
           for (Node n : allNodes) { 
            if (n.getKind().equals(k)) { 
             aMap.put(n.getCode(), n); 
            } 
           } 
           filteredNodes.put(k, aMap); 
          } 
          return true; 
         } 
        } 
    
    1

    코드 나 클래스 NodeImporter 및 클래스 노드로 결국

    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

    이것은 두 상자가 서로 상호 작용하는 방법을 이해하는 데 매우 도움이 감사합니다. 하나의 질문입니다.이 줄은 무엇을할까요?'subComboBox.setPrototypeDisplayValue ("XXXXXXXXXX"); // JDK1.4'? – NickAbbey

    +0

    [setPreferredSize] (http://stackoverflow.com/questions/8679421/why-jcombobox-ignore-prototypedisplayvalue) 필수 [화면 레이아웃] [LayoutManagers] (http://docs.oracle.com/javase/tutorial) /uiswing/layout/using.html) – mKorbel

    관련 문제