📄 svgcanvas.java
字号:
/* * Created on 23 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 java.awt.*;import java.util.*;import java.awt.dnd.*;import org.w3c.dom.*;import org.w3c.dom.svg.*;import org.apache.batik.bridge.*;import org.apache.batik.dom.svg.*;import org.apache.batik.swing.*;import org.apache.batik.gvt.*;import org.apache.batik.gvt.event.*;import fr.itris.glips.svgeditor.*;import java.io.*;import javax.swing.*;import java.awt.geom.*;import java.awt.image.*;/** * @author Jordi SUC * the class of the canvas of a SVG file */public class SVGCanvas extends JLayeredPane { /** * the constant for the grid layer */ public static final int GRID_LAYER = 0; /** * the constant for the grid layer */ public static final int BOTTOM_LAYER = 1; /** * the constant for the grid layer */ public static final int SELECTION_LAYER = 2; /** * the constant for the grid layer */ public static final int DRAW_LAYER = 3; /** * the constant for the grid layer */ public static final int TOP_LAYER = 4; /** * the labels */ private static String documentCreatingLabel, documentLoadingLabel = "", buildStartedLabel = "", renderingStartedLabel = ""; static { ResourceBundle bundle = SVGEditor.getBundle(); if (bundle != null) { try { documentCreatingLabel = bundle.getString("canvasDocumentCreatingLabel"); documentLoadingLabel = bundle.getString("canvasDocumentLoadingLabel"); buildStartedLabel = bundle.getString("canvasBuildStartedLabel"); renderingStartedLabel = bundle.getString("canvasRenderingStartedLabel"); } catch (Exception ex) { ex.printStackTrace(); } } } /** * whether to use the progress bar */ private boolean useMonitor = false; /** * the canvas */ private JPanel canvas; /** * the painters panel */ private JPanel paintersPanel; /** * the canvas uri */ private String uri = ""; /** * the canvas document */ private Document document; /** * the user agent */ private UserAgentAdapter userAgent; /** * the builder */ private GVTBuilder builder; /** * the bridge context */ private BridgeContext ctx; /** * the update manager */ private UpdateManager manager; /** * the update tracker */ private CanvasGraphicsNodeChangeListener graphicsNodeChangeAdapter; /** * the root graphics node */ private RootGraphicsNode gvtRoot; /** * the dirty areas to be updated */ private java.util.List<Area> dirtyAreas = new LinkedList<Area> (); /** * the offscreen image of the canvas */ private BufferedImage canvasOffscreenImage = null; /** * the rendered rectangle */ private Rectangle renderedRectangle = new Rectangle(0, 0, 1, 1), tmpRectangle = new Rectangle(0, 0, 0, 0); /** * the scrollpane that contains the canvas */ private SVGScrollPane scrollpane; /** * the file of the project this canvas is associated with */ private File projectFile = null; /** * the map associating an id integer to the list of the paint listeners for a layer */ private final Map<Integer, Set<CanvasPaintListener>> paintListeners = Collections.synchronizedMap(new HashMap<Integer, Set<CanvasPaintListener>> ()); /** * the boolean used by the repaint manager */ private boolean shouldRepaint = false; /** * whether the svg content should be repainted or not */ private boolean shouldRepaintSVGContent = false; /** * whether a part of the svg content should be updated or not */ private boolean shouldUpdateSVGContent = false; /** * the boolean enabling or disabling the refresh action when a paint listener is added or removed */ private boolean repaintEnabled = true; /** * the cursor that was set before the last change of the cursor */ private Cursor lastCursor = null; /** * the cursor used to show that the computer is busy and the default cursor */ private Cursor waitCursor, defaultCursor; /** * the boolean enabling or disabling the wait cursor */ private boolean enableWaitCursor = true; /** * whether the canvas is being disposed or not */ private boolean isDisposing = false; /** * the paint manager */ private Thread paintManager = new CanvasRepaintManager(); /** * the canvas' current scale and last scale */ private double scale = 1.0; /** * the editor */ private SVGEditor editor = null; /** * the svg frame */ private SVGFrame frame = null; /** * the progress bar dialog */ private SVGProgressBarDialog progressBar = null; /** * the drop target listener */ private CanvasDropTargetListener dropTargetListener = null; /** * the drop target */ private DropTarget dropTarget = null; /** * the constructor of the class * @param editor the editor * @param scrollpane the scrollpane into which the canvas will be inserted */ public SVGCanvas(SVGEditor editor, SVGScrollPane scrollpane) { this.editor = editor; this.scrollpane = scrollpane; this.frame = scrollpane.getSVGFrame(); setDoubleBuffered(true); //creating the paint listeners map structure paintListeners.put(GRID_LAYER, Collections.synchronizedSet(new HashSet<CanvasPaintListener> ())); paintListeners.put(BOTTOM_LAYER, Collections.synchronizedSet(new HashSet<CanvasPaintListener> ())); paintListeners.put(SELECTION_LAYER, Collections.synchronizedSet(new HashSet<CanvasPaintListener> ())); paintListeners.put(DRAW_LAYER, Collections.synchronizedSet(new HashSet<CanvasPaintListener> ())); paintListeners.put(TOP_LAYER, Collections.synchronizedSet(new HashSet<CanvasPaintListener> ())); //handling the cursors waitCursor = editor.getCursors().getCursor("wait"); defaultCursor = editor.getCursors().getCursor("default"); } /** * initializes the canvas * @param doc the document of the canvas */ protected void initializeCanvas(final Document doc) { this.document = doc; //creating the canvas canvas = new JPanel() { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); paintCanvas(g); //hiding the progress bar if it is not visible handleProgressBar(0, "", true, false); } }; canvas.setBackground(Color.white); //creating the painters panel paintersPanel = new JPanel() { @Override public void paintComponent(Graphics g) { super.paintComponent(g); drawPainters( (Graphics2D) g); } }; paintersPanel.setDoubleBuffered(true); paintersPanel.setOpaque(false); //filling the layered pane add(canvas); setLayer(canvas, JLayeredPane.DEFAULT_LAYER, -1); add(paintersPanel); setLayer(paintersPanel, JLayeredPane.DEFAULT_LAYER, 0); if (useMonitor) { //the thread for creating the graphics node Thread thread = new Thread() { @Override public void run() { initializeMain(); } }; thread.start(); } else { initializeMain(); } } /** * initializes the main elements */ protected void initializeMain() { //creating the graphics node try { userAgent = new UserAgentAdapter(); ctx = new BridgeContext(userAgent); builder = new GVTBuilder(); ctx.setDynamicState(BridgeContext.DYNAMIC); handleProgressBar(50, buildStartedLabel, false, useMonitor); GraphicsNode gvt = builder.build(ctx, document); if (gvt != null) { gvtRoot = gvt.getRoot(); } if (useMonitor) { initializeRemaining(); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { initializeRemaining(); } }); } } catch (Exception ex) { ex.printStackTrace(); } } /** * initializes the remaining elements */ protected void initializeRemaining() { //creating the update manager and tracker manager = new UpdateManager(ctx, gvtRoot, document); graphicsNodeChangeAdapter = new CanvasGraphicsNodeChangeListener(); if (gvtRoot != null) { gvtRoot.getRoot().addTreeGraphicsNodeChangeListener( graphicsNodeChangeAdapter); } //setting the size of the canvas Dimension scaledCanvasSize = getScaledCanvasSize(); setCanvasPreferredSize(scaledCanvasSize); frame.displayFrame(scaledCanvasSize); //notifies that the frames contained in the frame manager has changed frame.getSVGEditor().getFrameManager().frameChanged(); //creating the drop target listener dropTargetListener = new CanvasDropTargetListener(this, document); dropTarget = new DropTarget(this, dropTargetListener); dropTarget.setActive(true); frame.getStateBar().setSVGInfos(""); //adds a dispose runnable getScrollPane().getSVGFrame().addDisposeRunnable(new Runnable() { public void run() { synchronized (SVGCanvas.this) { isDisposing = true; } removeAll(); if (projectFile != null) { SVGEditor.getColorChooser().disposeColorsAndBlinkings(projectFile); } if (gvtRoot != null) { gvtRoot.getRoot().removeTreeGraphicsNodeChangeListener( graphicsNodeChangeAdapter); } if (dropTarget != null && dropTargetListener != null) { dropTarget.removeDropTargetListener(dropTargetListener); dropTarget.setActive(false); dropTarget.setComponent(null); dropTargetListener.dispose(); } removeAllPaintListeners(); paintListeners.clear(); document = null; builder = null; if (ctx != null) { ctx.dispose(); ctx = null; } userAgent = null; if (manager != null) { manager.interrupt(); manager = null; } gvtRoot = null; canvasOffscreenImage = null; projectFile = null; if (progressBar != null) { progressBar.disposeDialog(); progressBar.dispose(); } } }); handleProgressBar(75, renderingStartedLabel, false, false); //starting the paint manager paintManager.start(); } /** * initialize the progress bar * @param title the title */ protected void initializeProgressBar(String title) { if (useMonitor) { //creating the progress bar if (SVGEditor.getParent() instanceof JFrame) { progressBar = new SVGProgressBarDialog( (JFrame) SVGEditor.getParent(), ""); } else { progressBar = new SVGProgressBarDialog(new JFrame(""), ""); } //setting the title and the cancel runnable progressBar.setTitle(scrollpane.getSVGFrame().getName()); progressBar.setCancelRunnable(new Runnable() { public void run() { scrollpane.getSVGFrame().dispose(); } }); //showing the progress bar progressBar.setVisible(true); } } /** * handles the progress bar * @param value the current value * @param label the label * @param dispose whether the progress bar should be disposed * @param useAWTThread whether to execute the action in the AWT thread explicitly */ protected void handleProgressBar(final int value, final String label, final boolean dispose, boolean useAWTThread) { if (useMonitor) { Runnable runnable = new Runnable() { public void run() { if (dispose) { progressBar.setVisible(false); } else { progressBar.setProgressBarValueThreadSafe(value, 0, 100, label); } } }; if (useAWTThread) { SwingUtilities.invokeLater(runnable); } else { runnable.run(); } } } /** * creates a new svg document * @param width the width of the new document * @param height the height of the new document */ public void newDocument(final String width, final String height) { useMonitor = false; //initializing the progress bar initializeProgressBar(scrollpane.getSVGFrame().getShortName()); handleProgressBar(0, documentCreatingLabel, false, false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -