/* * File : JDomTreePanel.java * Created : 05-dec-2002 10:46 * By : fbusquets * * JClic - Authoring and playing system for educational activities * * Copyright (C) 2000 - 2018 Francesc Busquets & Departament * d'Educacio de la Generalitat de Catalunya * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details (see the LICENSE file). */ package edu.xtec.util; import edu.xtec.jclic.fileSystem.FileSystem; import edu.xtec.jclic.misc.Utils; import java.awt.Component; import java.awt.Dimension; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableModel; import javax.swing.tree.*; /** * @author Francesc Busquets (fbusquets@xtec.cat) * @version 13.09.17 */ public class JDomTreePanel extends javax.swing.JPanel { ResourceBridge rb; TreeSelectionListener treeSelectionListener; ListSelectionListener listSelectionListener; JDomTreeObject current; DefaultMutableTreeNode currentNode; FileSystem fs; String fileName; org.jdom.Element element; private DefaultMutableTreeNode clip; private boolean cut; /** Creates new form ProjectTreePanel */ public JDomTreePanel(org.jdom.Element element, ResourceBridge rb, FileSystem fs, String fileName) { this.rb = rb; this.fs = fs; this.fileName = fileName; this.element = element; initComponents(); initMembers(); tree.setModel(new DefaultTreeModel(JDomTreeObject.processNode(null, element, rb.getOptions()))); tree.addTreeSelectionListener(treeSelectionListener); table.getSelectionModel().addListSelectionListener(listSelectionListener); } private void initMembers() { treeSelectionListener = new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { checkEnabled(); } }; listSelectionListener = new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { delAttributeBtn.setEnabled(e.getFirstIndex() >= 0); } } }; } private void checkEnabled() { current = null; currentNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if (currentNode == null) { newElementBtn.setEnabled(false); delElementBtn.setEnabled(false); copyBtn.setEnabled(false); cutBtn.setEnabled(false); pasteBtn.setEnabled(false); } else { current = (JDomTreeObject) currentNode.getUserObject(); setTableModel(); String s = current.getElement().getText(); boolean empty = (s == null || s.length() == 0); boolean root = current.getElement().isRootElement(); newElementBtn.setEnabled(empty); delElementBtn.setEnabled(!root); copyBtn.setEnabled(!root); cutBtn.setEnabled(!root); pasteBtn.setEnabled(clip != null && empty && clip != currentNode && !clip.isNodeChild(currentNode)); } } private void setTableModel() { AbstractTableModel model = current; if (model == null) model = new DefaultTableModel(); table.setModel(model); model.fireTableStructureChanged(); newAttributeBtn.setEnabled(current != null); delAttributeBtn.setEnabled(false); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ private void initComponents() { // GEN-BEGIN:initComponents javax.swing.JPanel buttonsPanel; javax.swing.JSplitPane split; javax.swing.JPanel tablePanel; javax.swing.JScrollPane tableScroll; javax.swing.JPanel treeButtonsPanel; javax.swing.JPanel treePanel; javax.swing.JScrollPane treeScroll; split = new javax.swing.JSplitPane(); treePanel = new javax.swing.JPanel(); treeScroll = new javax.swing.JScrollPane(); tree = new javax.swing.JTree(); treeButtonsPanel = new javax.swing.JPanel(); newElementBtn = new javax.swing.JButton(); delElementBtn = new javax.swing.JButton(); copyBtn = new javax.swing.JButton(); pasteBtn = new javax.swing.JButton(); cutBtn = new javax.swing.JButton(); saveBtn = new javax.swing.JButton(); tablePanel = new javax.swing.JPanel(); tableScroll = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); buttonsPanel = new javax.swing.JPanel(); newAttributeBtn = new javax.swing.JButton(); delAttributeBtn = new javax.swing.JButton(); setLayout(new java.awt.BorderLayout()); treePanel.setLayout(new java.awt.BorderLayout()); treeScroll.setMinimumSize(new java.awt.Dimension(150, 22)); treeScroll.setViewportView(tree); treePanel.add(treeScroll, java.awt.BorderLayout.CENTER); newElementBtn .setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/new_element.gif"))); newElementBtn.setToolTipText(rb.getMsg("XML_NEW_ELEMENT")); newElementBtn.setEnabled(false); newElementBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { newElementBtnActionPerformed(evt); } }); treeButtonsPanel.add(newElementBtn); delElementBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/delete.gif"))); delElementBtn.setToolTipText(rb.getMsg("XML_DEL_ELEMENT")); delElementBtn.setEnabled(false); delElementBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { delElementBtnActionPerformed(evt); } }); treeButtonsPanel.add(delElementBtn); copyBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/copy.gif"))); copyBtn.setToolTipText(rb.getMsg("COPY")); copyBtn.setEnabled(false); copyBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { copyBtnActionPerformed(evt); } }); treeButtonsPanel.add(copyBtn); pasteBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/paste.gif"))); pasteBtn.setToolTipText(rb.getMsg("PASTE")); pasteBtn.setEnabled(false); pasteBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { pasteBtnActionPerformed(evt); } }); treeButtonsPanel.add(pasteBtn); cutBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/cut.gif"))); cutBtn.setToolTipText(rb.getMsg("CUT")); cutBtn.setEnabled(false); cutBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { cutBtnActionPerformed(evt); } }); treeButtonsPanel.add(cutBtn); saveBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/file_save.gif"))); saveBtn.setToolTipText(rb.getMsg("FILE_SAVE")); saveBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveBtnActionPerformed(evt); } }); treeButtonsPanel.add(saveBtn); treePanel.add(treeButtonsPanel, java.awt.BorderLayout.SOUTH); split.setLeftComponent(treePanel); tablePanel.setLayout(new java.awt.BorderLayout()); table.setModel(new javax.swing.table.DefaultTableModel(new Object[][] {}, new String[] {})); tableScroll.setViewportView(table); tablePanel.add(tableScroll, java.awt.BorderLayout.CENTER); newAttributeBtn .setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/new_attribute.gif"))); newAttributeBtn.setToolTipText(rb.getMsg("XML_NEW_ATTRIBUTE")); newAttributeBtn.setEnabled(false); newAttributeBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { newAttributeBtnActionPerformed(evt); } }); buttonsPanel.add(newAttributeBtn); delAttributeBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/edu/xtec/resources/icons/delete.gif"))); delAttributeBtn.setToolTipText(rb.getMsg("XML_DEL_ATTRIBUTE")); delAttributeBtn.setEnabled(false); delAttributeBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { delAttributeBtnActionPerformed(evt); } }); buttonsPanel.add(delAttributeBtn); tablePanel.add(buttonsPanel, java.awt.BorderLayout.SOUTH); split.setRightComponent(tablePanel); add(split, java.awt.BorderLayout.CENTER); } // GEN-END:initComponents private void cutBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_cutBtnActionPerformed if (currentNode != null && current != null && !current.getElement().isRootElement()) { clip = currentNode; cut = true; checkEnabled(); } } // GEN-LAST:event_cutBtnActionPerformed private void pasteBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_pasteBtnActionPerformed if (currentNode != null && current != null && clip != null && clip != currentNode && !clip.isNodeChild(currentNode)) { org.jdom.Element clipElement = ((JDomTreeObject) clip.getUserObject()).getElement(); org.jdom.Element el = (org.jdom.Element) clipElement.clone(); current.getElement().addContent(el); TreeNode node = JDomTreeObject.processNode(currentNode, el, rb.getOptions()); ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(currentNode); if (cut) { clipElement.detach(); ((DefaultTreeModel) tree.getModel()).removeNodeFromParent(clip); clip = null; } setTableModel(); checkEnabled(); } } // GEN-LAST:event_pasteBtnActionPerformed private void copyBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_copyBtnActionPerformed if (currentNode != null && current != null && !current.getElement().isRootElement()) { clip = currentNode; cut = false; checkEnabled(); } } // GEN-LAST:event_copyBtnActionPerformed private void saveBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_saveBtnActionPerformed if (fs == null) fs = new FileSystem(rb); int[] filters = { Utils.JCLIC_FF }; String result = fs.chooseFile(fileName + ".jclic", true, filters, rb.getOptions(), null, this, false); if (result != null) { String fullFileName = fs.getFullFileNamePath(result); try { FileOutputStream fos = fs.createSecureFileOutputStream(fullFileName, false); JDomUtility.saveDocument(fos, new org.jdom.Document(element)); fos.close(); // addRecentFile(fileName); } catch (Exception ex) { rb.getOptions().getMessages().showErrorWarning(this, "FILE_ERR_SAVING", fullFileName, ex, null); } } } // GEN-LAST:event_saveBtnActionPerformed private void delElementBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_delElementBtnActionPerformed if (currentNode != null && current != null && !current.getElement().isRootElement()) { if (clip == currentNode) clip = null; current.getElement().detach(); ((DefaultTreeModel) tree.getModel()).removeNodeFromParent(currentNode); setTableModel(); } } // GEN-LAST:event_delElementBtnActionPerformed private void newElementBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_newElementBtnActionPerformed if (currentNode != null && current != null) { String s = current.getElement().getText(); if (s == null || s.length() == 0) { JTextField[] fields = new JTextField[] { new JTextField() }; Dimension dim = new Dimension(100, 20); for (int i = 0; i < fields.length; i++) fields[i].setPreferredSize(dim); String[] promptKeys = new String[] { "XML_NAME" }; if (rb.getOptions().getMessages().showInputDlg(JDomTreePanel.this, null, promptKeys, fields, "XML_NEW_ELEMENT")) { String elementName = fields[0].getText(); if (elementName != null && elementName.length() > 0) { org.jdom.Element el = new org.jdom.Element(elementName); current.getElement().addContent(el); JDomTreeObject te = new JDomTreeObject(el, rb.getOptions()); DefaultMutableTreeNode node = new DefaultMutableTreeNode(te); ((DefaultTreeModel) tree.getModel()).insertNodeInto(node, currentNode, currentNode.getChildCount()); setTableModel(); } } } } } // GEN-LAST:event_newElementBtnActionPerformed private void delAttributeBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_delAttributeBtnActionPerformed if (current != null) { int r = table.getSelectedRow(); if (r >= 0) { if (r == 0) { List toRemove = new ArrayList(); List ls = current.getElement().getContent(); for (Object o : ls) { if (o instanceof org.jdom.Text) toRemove.add((org.jdom.Text) o); } ls.removeAll(toRemove); } else { String s = (String) current.getValueAt(r, 0); if (s != null) current.getElement().removeAttribute(s); } setTableModel(); } } } // GEN-LAST:event_delAttributeBtnActionPerformed private void newAttributeBtnActionPerformed(java.awt.event.ActionEvent evt) { // GEN-FIRST:event_newAttributeBtnActionPerformed if (current != null) { JTextField[] fields = new JTextField[] { new JTextField(), new JTextField() }; Dimension dim = new Dimension(100, 20); for (int i = 0; i < fields.length; i++) fields[i].setPreferredSize(dim); String[] promptKeys = new String[] { "XML_ATTRIBUTE", "XML_VALUE" }; if (rb.getOptions().getMessages().showInputDlg(JDomTreePanel.this, null, promptKeys, fields, "XML_NEW_ATTRIBUTE")) { String atrName = fields[0].getText(); String atrValue = fields[1].getText(); if (atrName != null && atrValue != null && atrName.length() > 0) { current.getElement().setAttribute(atrName, atrValue); setTableModel(); } } } } // GEN-LAST:event_newAttributeBtnActionPerformed public static org.jdom.Element editElement(Component parent, org.jdom.Element element, ResourceBridge rb, FileSystem fs, String fileName, String titleKey) { org.jdom.Element clon = (org.jdom.Element) element.clone(); boolean b = rb.getOptions().getMessages().showInputDlg(parent, new JDomTreePanel(clon, rb, fs, fileName), titleKey); return b ? clon : null; } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton copyBtn; private javax.swing.JButton cutBtn; private javax.swing.JButton delAttributeBtn; private javax.swing.JButton delElementBtn; private javax.swing.JButton newAttributeBtn; private javax.swing.JButton newElementBtn; private javax.swing.JButton pasteBtn; private javax.swing.JButton saveBtn; private javax.swing.JTable table; private javax.swing.JTree tree; // End of variables declaration//GEN-END:variables }