/*
* File : JDomTreePanel.java
* Created : 05-dec-2002 10:46
* By : fbusquets
*
* JClic - Authoring and playing system for educational activities
*
* Copyright (C) 2000 - 2005 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);
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<org.jdom.Text> toRemove=new ArrayList<org.jdom.Text>();
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
}