📄 svgframe.java
字号:
/* * Created on 25 mars 2004 * ============================================= GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 ============================================= GLIPS Graffiti Editor, a SVG Editor Copyright (C) 2003 Jordi SUC, Philippe Gil, SARL ITRIS This library 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 library 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 library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact : jordi.suc@itris.fr; philippe.gil@itris.fr ============================================= */package fr.itris.glips.svgeditor.canvas;import javax.swing.*;import javax.swing.border.*;import javax.swing.event.*;import org.apache.batik.bridge.*;import org.apache.batik.gvt.*;import java.util.*;import java.awt.*;import java.awt.geom.*;import java.awt.image.*;import java.beans.*;import fr.itris.glips.svgeditor.*;import java.io.*;import org.w3c.dom.*;import fr.itris.glips.svgeditor.resources.*;/** * @author Jordi SUC * the class linked with every SVG file that handles the SVGScrollPane, the menu items linked * with each SVG file, the state bar, etc */public class SVGFrame { /** * the editor */ private SVGEditor editor; /** * the panel into which the widgets are inserted */ private JPanel framePanel=new JPanel(); /** * the name of the SVGFrame */ private String name; /** * the scrollpane contained in this SVGFrame */ private SVGScrollPane scrollpane; /** * the menuitem associated with the frame in the menu bar */ private JRadioButtonMenuItem menuitem=new JRadioButtonMenuItem(); /** * the state bar */ private SVGStateBar statebar; /** * the interval frame into which the SVGFrame is inserted if the multi-windowed option is set to true */ private JInternalFrame internalFrame=null; /** * the list of the runnables enabling to dispose the frame */ private LinkedList<Runnable> disposeRunnables=new LinkedList<Runnable>(); /** * the boolean set to true if the SVG picture has been modified */ private boolean modified=false; /** * the font */ public final Font theFont=new Font("theFont", Font.ROMAN_BASELINE, 10); /** * the map associating a node to the set of the listeners to this node */ private Map<Node, HashSet<SVGDOMListener>> domListeners=Collections.synchronizedMap(new HashMap<Node, HashSet<SVGDOMListener>>()); /** * the map associating the id of a resource to the list of the nodes using this resource */ private Hashtable<String, LinkedList<Element>> usedResources=new Hashtable<String, LinkedList<Element>>(); /** * the constuctor of the class * @param editor the editor's object * @param name the name that will be linked with the SVG picture */ public SVGFrame(SVGEditor editor, String name){ super(); this.editor=editor; //filling the frame panel framePanel.setLayout(new BorderLayout()); //the state bar statebar=new SVGStateBar(); framePanel.add(statebar, BorderLayout.SOUTH); //the scrollpane scrollpane=new SVGScrollPane(editor, this); framePanel.add(scrollpane, BorderLayout.CENTER); if(editor.isMultiWindow()){ //creating the internal frame internalFrame=new JInternalFrame("", true, true, true, true); //sets the icon final ImageIcon editorIcon=SVGResource.getIcon("EditorInner", false); internalFrame.setFrameIcon(editorIcon); framePanel.setBorder(new EmptyBorder(3, 3, 3, 1)); //setting the location of the frame Rectangle bounds=getSVGEditor().getPreferredWidgetBounds("frame"); int nb=editor.getFrameManager().getFrameNumber(), offset=30, beginX=75, beginY=0; if(bounds!=null){ beginX=bounds.x; beginY=bounds.y; } internalFrame.setLocation(beginX+nb*offset,beginY+nb*offset); internalFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); //adds an internal frame listener final InternalFrameListener internalFrameListener=new InternalFrameAdapter(){ @Override public void internalFrameClosing(InternalFrameEvent e) { close(); } }; internalFrame.addInternalFrameListener(internalFrameListener); //the listener to the focus changes final VetoableChangeListener vetoableChangeListener=new VetoableChangeListener(){ public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { if( evt.getPropertyName()!=null && evt.getPropertyName().equals("selected") && getSVGEditor().getFrameManager().getCurrentFrame()!=SVGFrame.this && ((Boolean)evt.getNewValue()).booleanValue()){ getSVGEditor().getFrameManager().setCurrentFrame(SVGFrame.this.getName()); } } }; internalFrame.addVetoableChangeListener(vetoableChangeListener); //adds a dispose runnable disposeRunnables.add(new Runnable(){ public void run() { usedResources.clear(); internalFrame.removeInternalFrameListener(internalFrameListener); internalFrame.removeVetoableChangeListener(vetoableChangeListener); } }); }else{ //adds the SVGFrame to the desktop panel contained in the main frame editor.getDesktop().add(framePanel); } setName(name); } /** * displays this frame * @param canvasSize the canvas size */ public void displayFrame(Dimension canvasSize){ if(internalFrame!=null && canvasSize!=null){ //computing the size of the internal frame int border=100; Dimension frameSize=new Dimension(canvasSize.width+border, canvasSize.height+border); Dimension availableSpace=new Dimension( editor.getDesktop().getWidth()-internalFrame.getX(), editor.getDesktop().getHeight()-internalFrame.getY()); if(frameSize.width>availableSpace.width){ frameSize.width=availableSpace.width; } if(frameSize.height>availableSpace.height){ frameSize.height=availableSpace.height; } internalFrame.setSize(frameSize); internalFrame.setPreferredSize(frameSize); internalFrame.getContentPane().add(framePanel); //adds the internalFrame to the desktop panel contained in the main frame editor.getDesktop().add(internalFrame); internalFrame.setVisible(true); } } /** * closes the frame */ public void close() { Object obj=null; if(getSVGEditor().getSVGModuleLoader()!=null){ obj=getSVGEditor().getSVGModuleLoader().getModule("SaveClose"); } if(obj!=null){ Class[] cargs={SVGFrame.class}; Object[] args={this}; try{ obj.getClass().getMethod("closeAction", cargs).invoke(obj,args); }catch (Exception ex){} } } /** * @return whether this frame is selected or not */ public boolean isSelected(){ SVGFrame currentFrame=getSVGEditor().getFrameManager().getCurrentFrame(); if(currentFrame!=null && currentFrame.equals(this)){ if(internalFrame!=null){ return internalFrame.isSelected(); } return true; } return false; } /** * handles the initial operations on the svg document * @param doc the svg document * @param scaledSize the scaled size of the canvas */ public void handleInitialDOMOperations(Document doc, Dimension scaledSize){ if(doc!=null){ Element root=doc.getDocumentElement(); if(root!=null && root.getAttribute("viewBox").equals("")){ root.setAttributeNS(null, "viewBox", "0 0 "+(int)scaledSize.getWidth()+" "+(int)scaledSize.getHeight()); } if(root!=null){ //getting the map associating the id of a resource to the resource node LinkedList<String> resourceNames=new LinkedList<String>(); resourceNames.add("linearGradient"); resourceNames.add("radialGradient"); resourceNames.add("pattern"); resourceNames.add("marker"); final String styleAttributeName="style", gNodeName="g", regex1="\\n+", regex2="\\r+", regex3="\\t+"; Hashtable<String, Element> resources=getResourcesFromDefs(doc, resourceNames); //applying modifications on the dom Node node=null; Element el=null; String nsp=root.getNamespaceURI(); LinkedList<Element> nodesList=null; String style="", nodeValue=""; //the set of the nodes to remove HashSet<Node> nodesToRemove=new HashSet<Node>(); //the list of the group nodes LinkedList<Element> groupNodes=new LinkedList<Element>(); for(NodeIterator nit=new NodeIterator(root); nit.hasNext();){ node=nit.next(); if(node!=null && nsp.equals(node.getNamespaceURI()) && node instanceof Element){ el=(Element)node; //normalizing the node editor.getSVGToolkit().normalizeNode(el); //checking the color values consistency SVGEditor.getColorChooser().checkColorString(SVGFrame.this, el); //getting the style attribute style=el.getAttribute(styleAttributeName); if(style!=null && ! style.equals("")){ //for each resource id, checks if it is contained in the style attribute for(String id : resources.keySet()){ nodesList=usedResources.get(id); //adds the node in the used resource map if(id!=null && ! id.equals("") && style.indexOf("#".concat(id))!=-1){ if(nodesList==null){ nodesList=new LinkedList<Element>(); usedResources.put(id, nodesList); } nodesList.add(el); } } } if(node.getNodeName().equals(gNodeName)){ groupNodes.add(el); } }else if(node!=null && node instanceof Text){ nodeValue=node.getNodeValue(); if(nodeValue!=null && ! nodeValue.equals("")){ nodeValue=nodeValue.replaceAll(regex1, ""); nodeValue=nodeValue.replaceAll(regex2, ""); nodeValue=nodeValue.replaceAll(regex3, ""); } if(nodeValue==null || nodeValue.equals("")){ nodesToRemove.add(node); }else{ node.setNodeValue(nodeValue); } } } //removing the unused text nodes for(Node textNode : nodesToRemove){ textNode.getParentNode().removeChild(textNode); } //normalizes the group nodes for(Element groupElement : groupNodes){ if(groupElement!=null){ //normalizing the node editor.getSVGToolkit().normalizeGroupNode(groupElement); } } } } } /** * adds the given id of a resource and its associated node to the map of the nodes using a resource * @param resourceId the id of a resource * @param node the node using the given resource */ public synchronized void addNodeUsingResource(String resourceId, Node node){ if(resourceId!=null && ! resourceId.equals("") && node!=null){ LinkedList<Element> nodesList=null; //checking if the id of the resource is contained in the map if(usedResources.containsKey(resourceId)){ try{ //getting the associated list of nodes nodesList=usedResources.get(resourceId); }catch (Exception ex){} } if(nodesList==null){ //if the id was not contained in the map, creates a new list of nodes nodesList=new LinkedList<Element>(); usedResources.put(resourceId, nodesList); } if(nodesList!=null){ //adding the node to the list nodesList.add((Element)node); } } } /** * adds the given id of a resource and its associated node to the map of the nodes using a resource * @param resourceId the id of a resource * @param list the nodes using the given resource */ public synchronized void addNodesUsingResource(String resourceId, LinkedList<Element> list){ if(resourceId!=null && ! resourceId.equals("") && list!=null){ LinkedList<Element> nodesList=null; //checking if the id of the resource is contained in the map if(usedResources.containsKey(resourceId)){ try{ //getting the associated list of nodes nodesList=usedResources.get(resourceId); }catch (Exception ex){} } if(nodesList==null){ //if the id was not contained in the map, creates a new list of nodes nodesList=new LinkedList<Element>(); usedResources.put(resourceId, nodesList); } for(Element cur : new HashSet<Element>(list)){ if(cur!=null){ //adding the node to the list nodesList.add(cur); } } } } /** * removes the given id of a resource and its associated node to the map of the nodes using a resource * @param resourceId the id of a resource * @param node the node using the given resource */ public synchronized void removeNodeUsingResource(String resourceId, Node node){ if(resourceId!=null && ! resourceId.equals("") && node!=null){ LinkedList<Element> nodesList=null; //checking if the id of the resource is contained in the map if(usedResources.containsKey(resourceId)){ try{ //getting the associated list of nodes nodesList=usedResources.get(resourceId); }catch (Exception ex){} } if(nodesList!=null && nodesList.contains(node)){ //removing the node from the list nodesList.remove(node); } } } /** * adds the given id of a resource and its associated node to the map of the nodes using a resource * @param resourceId the id of a resource * @param list the nodes using the given resource */ public synchronized void removeNodesUsingResource(String resourceId, LinkedList<Element> list){ if(resourceId!=null && ! resourceId.equals("") && list!=null){ LinkedList<Element> nodesList=null; //checking if the id of the resource is contained in the map
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -