2014-04-01 32 views
1

我已經創建了一個應用程序,該應用程序引用了從XML文件分配給JTree組件的用戶列表,然後可以查看和編輯它們。到目前爲止我的代碼:我需要將我的DOM與「持久層」分開

public class DomainModel extends JFrame { 

    private JTree tree; 
    private String fileSource = "users.xml"; 
    private NodeList listOfUsers; 
    private String objID; 

    private JTextField textName; 
    private JTextField textAge; 
    private JTextField textDOB; 
    private JButton editBtn; 

    private JTextField textEditName; 
    private JTextField textEditAge; 
    private JTextField textEditDOB; 
    private JButton saveBtn; 
    private JButton cancelBtn; 

    public DomainModel() { 

     createGUI(); 
    } 

    public void createGUI() { 

     JPanel mainPanel = new JPanel(); 
     mainPanel.setLayout(new GridLayout(1, 2)); 

     JPanel leftPanel = new JPanel(); 
     leftPanel.setLayout(new GridLayout(1, 1)); 
     leftPanel.setBorder(BorderFactory.createCompoundBorder(
       BorderFactory.createTitledBorder("Domain Model"), 
       BorderFactory.createEmptyBorder(10, 10, 10, 10))); 

     createTree(); 

     tree.setLayout(new GridLayout(1, 1)); 
     tree.setBorder(new EmptyBorder(10, 10, 10, 10)); 
     tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { 

      public void valueChanged(TreeSelectionEvent e) { 

       nodeChange(e); 
      } 
     }); 

     JPanel rightPanel = new JPanel(); 
     rightPanel.setLayout(new GridLayout(2, 1)); 

     JPanel detailsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 
     detailsPanel.setBorder(BorderFactory.createCompoundBorder(
       BorderFactory.createTitledBorder("Node Details"), 
       BorderFactory.createEmptyBorder(5, 5, 5, 5))); 

     JLabel labelName = new JLabel("Name"); 
     JLabel labelAge = new JLabel("Age"); 
     JLabel labelDOB = new JLabel("DOB"); 

     textName = new JTextField(15); 
     textAge = new JTextField(15); 
     textDOB = new JTextField(15); 

     editBtn = new JButton("Edit"); 
     editBtn.addActionListener(new ButtonListener()); 

     detailsPanel.add(labelName); 
     detailsPanel.add(textName); 
     detailsPanel.add(labelAge); 
     detailsPanel.add(textAge); 
     detailsPanel.add(labelDOB); 
     detailsPanel.add(textDOB); 
     detailsPanel.add(editBtn); 

     JPanel editPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 
     editPanel.setBorder(BorderFactory.createCompoundBorder(
       BorderFactory.createTitledBorder("Edit Node"), 
       BorderFactory.createEmptyBorder(5, 5, 5, 5))); 

     JLabel labelEditName = new JLabel("Name"); 
     JLabel labelEditAge = new JLabel("Age"); 
     JLabel labelEditDOB = new JLabel("DOB"); 

     textEditName = new JTextField(15); 
     textEditAge = new JTextField(15); 
     textEditDOB = new JTextField(15); 

     saveBtn = new JButton("Save"); 
     saveBtn.addActionListener(new ButtonListener()); 

     cancelBtn = new JButton("Cancel"); 
     cancelBtn.addActionListener(new ButtonListener()); 

     editPanel.add(labelEditName); 
     editPanel.add(textEditName); 
     editPanel.add(labelEditAge); 
     editPanel.add(textEditAge); 
     editPanel.add(labelEditDOB); 
     editPanel.add(textEditDOB); 
     editPanel.add(saveBtn); 
     editPanel.add(cancelBtn); 

     leftPanel.add(new JScrollPane(tree)); 
     rightPanel.add(detailsPanel); 
     rightPanel.add(editPanel); 
     mainPanel.add(leftPanel); 
     mainPanel.add(rightPanel); 
     mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); 
     add(mainPanel); 

     nullDetails(); 
     nullEdit(); 

     setTitle("Domain Model Example"); 
     setSize(525, 350); 
     setLocationRelativeTo(null); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setResizable(false); 
    } 

    public void createTree(){ 

     DefaultMutableTreeNode root = new DefaultMutableTreeNode("users"); 

     try { 

      DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 
      Document doc = docBuilder.parse(new File(fileSource)); 

      listOfUsers = doc.getElementsByTagName("user"); 

      // for each user in the node list, add it to the JTree 
      for (int i = 0; i < listOfUsers.getLength(); i++) { 

       Element el = (Element) listOfUsers.item(i); 
       String id = el.getAttribute("id"); 
       File file = new File(id); 
       DefaultMutableTreeNode node = new DefaultMutableTreeNode(file); 
       root.add(node); 
      } 

      tree = new JTree(root); 

     } catch (Exception e) { 

      e.printStackTrace(); 
     } 
    } 

    public void nodeChange(TreeSelectionEvent e) { 

     nullDetails(); 
     nullEdit(); 

     objID = e.getPath().getLastPathComponent().toString(); 

     // for each user in the node list, find an ID match 
     for (int i = 0; i < listOfUsers.getLength(); i++) { 

      Element el = (Element) listOfUsers.item(i); 
      String strID = el.getAttribute("id"); 

      // if an ID match has been found, display it's details 
      if (objID.equals(strID)) { 

       String strName = el.getElementsByTagName("name").item(0).getTextContent(); 
       String strAge= el.getElementsByTagName("age").item(0).getTextContent(); 
       String strDOB = el.getElementsByTagName("dob").item(0).getTextContent(); 

       textName.setText(strName); 
       textAge.setText(strAge); 
       textDOB.setText(strDOB); 
       editBtn.setEnabled(true); 
       break; 
      } 
     } 
    } 

    public void nullDetails() { 

     textName.setText(null); 
     textAge.setText(null); 
     textDOB.setText(null); 

     textName.setEnabled(false); 
     textAge.setEnabled(false); 
     textDOB.setEnabled(false); 

     editBtn.setEnabled(false); 
    } 

    public void nullEdit() { 

     textEditName.setText(null); 
     textEditAge.setText(null); 
     textEditDOB.setText(null); 

     textEditName.setEnabled(false); 
     textEditAge.setEnabled(false); 
     textEditDOB.setEnabled(false); 

     saveBtn.setEnabled(false); 
     cancelBtn.setEnabled(false); 
    } 

    class ButtonListener implements ActionListener { 

     public void actionPerformed(ActionEvent a) { 

      JButton b = (JButton) a.getSource(); 
      String pressedBtn = b.getText(); 

      // if the Edit button has been clicked 
      if (pressedBtn.equals("Edit")) { 

       textEditName.setText(textName.getText()); 
       textEditAge.setText(textAge.getText()); 
       textEditDOB.setText(textDOB.getText()); 

       textEditName.setEnabled(true); 
       textEditAge.setEnabled(true); 
       textEditDOB.setEnabled(true); 

       saveBtn.setEnabled(true); 
       cancelBtn.setEnabled(true); 

      } else if (pressedBtn.equals("Save")) { // if the Save button has been clicked 

       int reply = JOptionPane.showConfirmDialog(null, "Are you sure you want to save?", "Save", JOptionPane.YES_NO_OPTION); 

       if (reply == JOptionPane.YES_OPTION) { 

        updateXML(); 
       } 

      } else { // else the Cancel button has been clicked 

       nullEdit(); 
      } 
     } 
    } 

    public void updateXML(){ 

     // for each user in the node list, find an ID match 
     for (int i = 0; i < listOfUsers.getLength(); i++) { 

      Element el = (Element) listOfUsers.item(i); 
      String strId = el.getAttribute("id"); 

      // if an ID match has been found, update the component's details 
      if (objID.equals(strId)) { 

       try { 

        String strName = textEditName.getText(); 
        String strAge = textEditAge.getText(); 
        String strDOB = textEditDOB.getText(); 

        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 
        DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 
        Document doc = docBuilder.parse(new File(fileSource)); 

        doc.getElementsByTagName("name").item(i).setTextContent(strName); 
        doc.getElementsByTagName("age").item(i).setTextContent(strAge); 
        doc.getElementsByTagName("dob").item(i).setTextContent(strDOB); 

        TransformerFactory transformerFactory = TransformerFactory.newInstance(); 
        Transformer transformer = transformerFactory.newTransformer(); 
        DOMSource domSource = new DOMSource(doc); 
        StreamResult streamResult = new StreamResult(new File(fileSource)); 

        transformer.transform(domSource, streamResult); 

        el.getElementsByTagName("name").item(i).setTextContent(strName); 
        el.getElementsByTagName("age").item(i).setTextContent(strAge); 
        el.getElementsByTagName("dob").item(i).setTextContent(strDOB); 

        textName.setText(strName); 
        textAge.setText(strAge); 
        textDOB.setText(strDOB); 
        editBtn.setEnabled(true); 

        break; 

       } catch (Exception e) { 

        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 

       DomainModel dm = new DomainModel(); 
       dm.setVisible(true); 
      } 
     }); 
    } 
} 

我現在正在實施的一些附加功能,而我堅持到了DOM從「持久層」分開。我試圖對此進行進一步的研究,但是我仍然對做什麼或者做什麼有點模糊。

非常感謝。

+0

谷歌的模型 - 視圖 - 控制器設計模式和類似的方法 - 簡而言之,你應該把你的代碼分成幾層。持久層應該在內部處理數據操作,並且有一些可以從UI調用的接口。表示層應該是分開的,它應該只包含創建控件和從持久性接口調用方法的簡單代碼段。 –

+0

感謝您的及時回覆。我熟悉MVC方法,因此在這種情況下,createTree()方法是否可以歸類到Model中?它有點令人困惑,因爲我還被要求演示MVC方法;所以在技術上他們都是同樣的事情。再次,非常感謝。 – Kurtiss

+0

實際上等待......它顯示在用戶界面上,因此它可以是視圖。但是,它需要再次使用XML文件中的數據才能顯示它,以便將其分類爲控制器。 – Kurtiss

回答

1

我從評論切換到答案,因爲我需要格式化這裏;)

首先,這種方法createTree應該分裂成更小的部分,因爲它實際上混合所有圖層。控制器不應該關心你有什麼UI控制,它不應該關心它使用的是什麼類型的數據存儲。想象一下,一個pseudecode這樣的:

interface DataStore { // model 
    List<User> getUsers(); 
    void saveNewUser(User user); 
} 
class XmlDataStoreImpl implements DataStore { ... } 
interface Ui { // view 
    void showUsers(List<User> users); 
    User getUserDataFromControls(); 
} 
class DomainModel extends JFrame implements Ui { // view 
    static void main(String[] args) { 
     DataStore dataStore = new XmlDataStoreImpl("users.xml"); 
     AppController app = new AppController(dataStore, this); 
     app.loadUsers(); 
    } 
    void init() { 
     createControls(); // create empty JTree object and other controlls 
    } 
} 
class AppController { // controller 
    DataStore dataStore; 
    Ui ui; 
    public AppController(DataStore ds, Ui ui) { 
     ... 
     ui.init(); 
    } 
    void loadUsers() { 
     ui.showUsers(dataStore.getUsers()); // this line is your "createTree" but independent on implementations of model and view 
    } 
    void saveButtonClickedHandler() { 
     User user = ui.getUserDataFromControls(); 
     dataStore.saveNewUser(user); 
    } 
} 
+0

感謝您的及時答覆,並抱歉badgering評論XP – Kurtiss

+0

我一直在嘗試我自己的版本,這是目前不完全功能。我創建了一個名爲User的類來創建用戶對象,一個名爲UserHandler的處理程序,它構成了用於創建用戶對象並將它們添加到列表的藍圖,只需使用XML文件調用即可,我也一樣創建了一個擴展名爲GUI的JFrame的類,它所做的只是形成應用程序的UI結構。 – Kurtiss