/* * Project Info: http://jcae.sourceforge.net * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 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 Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * (C) Copyright 2005-2010, by EADS France */ package org.jcae.netbeans.mesh; import java.awt.EventQueue; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.XMLEncoder; import java.io.File; import java.io.IOException; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; import java.util.prefs.Preferences; import org.jcae.mesh.xmldata.Group; import org.jcae.mesh.xmldata.Groups; import org.jcae.netbeans.Utilities; import org.jcae.netbeans.options.OptionNode; import org.jcae.netbeans.viewer3d.ViewManager; import org.jcae.vtk.AmibeToMesh; import org.jcae.vtk.View; import org.jcae.vtk.Viewable; import org.openide.ErrorManager; import org.openide.cookies.SaveCookie; import org.openide.filesystems.FileAttributeEvent; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileEvent; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileRenameEvent; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObjectExistsException; import org.openide.loaders.MultiDataObject; import org.openide.loaders.MultiFileLoader; import org.openide.nodes.Node; import org.openide.util.Exceptions; import org.openide.util.NbPreferences; import org.xml.sax.SAXException; /** * * @author Gautam Botrel */ public class AmibeDataObject extends MultiDataObject implements SaveCookie { private int threshold = 400000; private boolean listenFlag; private void refresh() { final View view = ViewManager.getDefault().getCurrentView(); for (Viewable v : view.getViewables()) { if (v instanceof AmibeNViewable) { AmibeNViewable av = (AmibeNViewable) v; try { if(av.getDataObject().equals(AmibeDataObject.this)) { AmibeToMesh reader = new AmibeToMesh( getGroups().getMeshFile(), groupsToID(getGroups().getGroups())); if(reader.getNumberOfTriangles() > threshold ) continue; av.addTriangles(reader.getTriangles()); av.addBeams(reader.getBeams()); view.Render(); } } catch (SAXException ex) { Exceptions.printStackTrace(ex); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } } } private final FileChangeListener fileListener = new FileChangeListener() { public void fileFolderCreated(FileEvent fe) {} public void fileDataCreated(FileEvent fe) {} public void fileChanged(FileEvent fe) { EventQueue.invokeLater(new Runnable(){ public void run() { refresh(); } }); } public void fileDeleted(FileEvent fe) {} public void fileRenamed(FileRenameEvent fe) {} public void fileAttributeChanged(FileAttributeEvent fe) {} }; public AmibeDataObject(FileObject arg0, MultiFileLoader arg1, Mesh mesh) throws DataObjectExistsException { super(arg0, arg1); this.mesh = mesh; mesh.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { setModified(true); } }); Preferences pref = OptionNode.REFRESH_THRESHOLD.getPreferences(); pref.addPreferenceChangeListener(new PreferenceChangeListener() { public void preferenceChange(PreferenceChangeEvent evt) { if (evt.getKey().equals(OptionNode.REFRESH_THRESHOLD.getPreferenceName())) { threshold = Integer.parseInt(evt.getNewValue()); } } }); } public String getDisplayName() { FileObject xmlMesh = getXMLMesh(false); if(xmlMesh == null) return getPrimaryFile().getName(); else { String s = xmlMesh.getName(); return s.substring(0, s.length()-"_mesh".length()); } } /** Return the secondary entry which ends by _mesh.xml */ private FileObject getXMLMesh(boolean create) { FileObject toReturn = null; for(Entry e:secondaryEntries()) { String s = e.getFile().getName(); if(s.endsWith("_mesh")) toReturn = e.getFile(); } if(create && toReturn==null) { String name = getPrimaryFile().getName(); try { FileObject parent = getPrimaryFile().getParent(); FileLock l = parent.lock(); toReturn = parent.createData(name + "_mesh.xml"); l.releaseLock(); } catch (IOException ex) { Exceptions.printStackTrace(ex); } } return toReturn; } @Override protected Node createNodeDelegate() { AmibeNode r = new AmibeNode(this); if(!isTemplate()) { r.updateGeomNode(); refreshGroups(r); } return r; } private Mesh mesh; private Groups groups; public Mesh getMesh() { return mesh; } public String getMeshDirectory() { String ref=FileUtil.toFile(getPrimaryFile().getParent()).getPath(); return Utilities.absoluteFileName(getMesh().getMeshFile(), ref); } public void save() throws IOException { FileLock l = null; XMLEncoder encoder = null; try { FileObject out = getXMLMesh(true); l = out.lock(); encoder = new XMLEncoder(out.getOutputStream(l)); encoder.writeObject(mesh); setModified(false); } catch(IOException ex) { ErrorManager.getDefault().notify(ex); } finally { if(encoder!=null) encoder.close(); if(l!=null) l.releaseLock(); } } @Override protected FileObject handleRename(String name) throws IOException { FileObject toReturn = super.handleRename(name); mesh.setMeshFile(toReturn.getNameExt()); refreshGroups(); return toReturn; } public void refreshGroups() { refreshGroups((AmibeNode) getNodeDelegate()); refreshHeader(); } /** * private implementation to be called by createNodeDelegate. * Avoid a stack overflow when calling getNodeDelegate. */ private void refreshGroups(AmibeNode amibeNode) { String meshDir=getMeshDirectory(); File xmlFile=new File(meshDir, "jcae3d"); if (xmlFile.exists()) groups = Groups.getGroups(meshDir); amibeNode.setGroups(groups); } public Groups getGroups() { return groups; } public void refreshHeader() { FileObject[] amibeChildren = getPrimaryFile().getChildren(); for (int i = 0; i < amibeChildren.length; i++) { if (amibeChildren[i].getName().equalsIgnoreCase("jcae3d")) { amibeChildren[i].refresh(); break; } } } public void addListener() { if(!listenFlag) { FileObject f = getPrimaryFile().getFileObject("jcae3d"); if(f != null) { FileUtil.addFileChangeListener(fileListener, FileUtil.toFile(f)); listenFlag = true; } } } public void removeListener() { FileObject f = getPrimaryFile().getFileObject("jcae3d"); if(f != null) FileUtil.removeFileChangeListener(fileListener, FileUtil.toFile(f)); listenFlag = false; } private String[] groupsToID(Group[] groupsToDisplay) { String[] idGroupsDisplayed = new String[groupsToDisplay.length]; for (int i = 0; i < groupsToDisplay.length; i++) { idGroupsDisplayed[i] = groupsToDisplay[i].getName(); } return idGroupsDisplayed; } }