svwindow.java

来自「一个google的OCR源码」· Java 代码 · 共 644 行 · 第 1/2 页

JAVA
644
字号
// Copyright 2007 Google Inc. All Rights Reserved.//// Licensed under the Apache License, Version 2.0 (the "License"); You may not// use this file except in compliance with the License. You may obtain a copy of// the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by// applicable law or agreed to in writing, software distributed under the// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS// OF ANY KIND, either express or implied. See the License for the specific// language governing permissions and limitations under the License.package com.google.scrollview.ui;import com.google.scrollview.ScrollView;import com.google.scrollview.events.SVEvent;import com.google.scrollview.events.SVEventHandler;import com.google.scrollview.events.SVEventType;import com.google.scrollview.ui.SVImageHandler;import com.google.scrollview.ui.SVMenuBar;import com.google.scrollview.ui.SVPopupMenu;import edu.umd.cs.piccolo.PCamera;import edu.umd.cs.piccolo.PCanvas;import edu.umd.cs.piccolo.PLayer;import edu.umd.cs.piccolo.nodes.PImage;import edu.umd.cs.piccolo.nodes.PPath;import edu.umd.cs.piccolo.nodes.PText;import edu.umd.cs.piccolo.util.PPaintContext;import edu.umd.cs.piccolox.swing.PScrollPane;import java.awt.BasicStroke;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Font;import java.awt.GraphicsEnvironment;import java.awt.geom.IllegalPathStateException;import java.awt.Rectangle;import java.awt.TextArea;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.SwingUtilities;import javax.swing.WindowConstants;/** * The SVWindow is the top-level ui class. It should get instantiated whenever * the user intends to create a new window. It contains helper functions to draw * on the canvas, add new menu items, show modal dialogs etc. * * @author wanke@google.com */public class SVWindow extends JFrame {  /**   * Constants defining the maximum initial size of the window.   */  private static final int MAX_WINDOW_X = 1000;  private static final int MAX_WINDOW_Y = 800;  /* Constant defining the (approx) height of the default message box*/  private static final int DEF_MESSAGEBOX_HEIGHT = 200;  /** Constant defining the "speed" at which to zoom in and out. */  public static final double SCALING_FACTOR = 2;  /** The top level layer we add our PNodes to (root node). */  PLayer layer;  /** The current color of the pen. It is used to draw edges, text, etc. */  Color currentPenColor;  /**   * The current color of the brush. It is used to draw the interior of   * primitives.   */  Color currentBrushColor;  /** The system name of the current font we are using (e.g.   *  "Times New Roman"). */  Font currentFont;  /** The stroke width to be used. */  // This really needs to be a fixed width stroke as the basic stroke is  // anti-aliased and gets too faint, but the piccolo fixed width stroke  // is too buggy and generates missing initial moveto in path definition  // errors with a IllegalPathStateException that cannot be caught because  // it is in the automatic repaint function. If we can fix the exceptions  // in piccolo, then we can use the following instead of BasicStroke:  //   import edu.umd.cs.piccolox.util.PFixedWidthStroke;  //   PFixedWidthStroke stroke = new PFixedWidthStroke(0.5f);  // Instead we use the BasicStroke and turn off anti-aliasing.  BasicStroke stroke = new BasicStroke(0.5f);  /**   * A unique representation for the window, also known by the client. It is   * used when sending messages from server to client to identify him.   */  public int hash;  /**   * The total number of created Windows. If this ever reaches 0 (apart from the   * beginning), quit the server.   */  public static int nrWindows = 0;  /**   * The Canvas, MessageBox, EventHandler, Menubar and Popupmenu associated with   * this window.   */  private SVEventHandler svEventHandler = null;  private SVMenuBar svMenuBar = null;  private TextArea ta = null;  public SVPopupMenu svPuMenu = null;  public PCanvas canvas;  private int winSizeX;  private int winSizeY;  /** Set the brush to an RGB color */  public void brush(int red, int green, int blue) {    brush(red, green, blue, 255);  }  /** Set the brush to an RGBA color */  public void brush(int red, int green, int blue, int alpha) {    // If alpha is zero, use a null brush to save rendering time.    if (alpha == 0) {      currentBrushColor = null;    } else {      currentBrushColor = new Color(red, green, blue, alpha);    }  }  /** Erase all content from the window, but do not destroy it. */  public void clear() {    layer.removeAllChildren();  }  /**   * Start setting up a new image. The server will now expect image data until   * the image is complete.   *   * @param internalName The unique name of the new image   * @param width Image width   * @param height Image height   * @param bitsPerPixel The bit depth (currently supported: 1 (binary) and 32   *        (ARGB))   */  public void createImage(String internalName, int width, int height,      int bitsPerPixel) {    SVImageHandler.createImage(internalName, width, height, bitsPerPixel);  }  /**   * Start setting up a new polyline. The server will now expect   * polyline data until the polyline is complete.   *   * @param length number of coordinate pairs   */  public void createPolyline(int length) {    ScrollView.polylineXCoords = new float[length];    ScrollView.polylineYCoords = new float[length];    ScrollView.polylineSize = length;    ScrollView.polylineScanned = 0;  }  /**   * Draw the now complete polyline.   */  public void drawPolyline() {    PPath pn = PPath.createPolyline(ScrollView.polylineXCoords,                                    ScrollView.polylineYCoords);    ScrollView.polylineSize = 0;    pn.setStrokePaint(currentPenColor);    pn.setPaint(null);  // Don't fill the polygon - this is just a polyline.    pn.setStroke(stroke);    layer.addChild(pn);  }  /**   * Construct a new SVWindow and set it visible.   *   * @param name Title of the window.   * @param hash Unique internal representation. This has to be the same as   *        defined by the client, as they use this to refer to the windows.   * @param posX X position of where to draw the window (upper left).   * @param posY Y position of where to draw the window (upper left).   * @param sizeX The width of the window.   * @param sizeY The height of the window.   * @param canvasSizeX The canvas width of the window.   * @param canvasSizeY The canvas height of the window.   */  public SVWindow(String name, int hash, int posX, int posY, int sizeX,                  int sizeY, int canvasSizeX, int canvasSizeY) {    super(name);    // Provide defaults for sizes.    if (sizeX == 0) sizeX = canvasSizeX;    if (sizeY == 0) sizeY = canvasSizeY;    if (canvasSizeX == 0) canvasSizeX = sizeX;    if (canvasSizeY == 0) canvasSizeY = sizeY;    // Initialize variables    nrWindows++;    this.hash = hash;    this.svEventHandler = new SVEventHandler(this);    this.currentPenColor = Color.BLACK;    this.currentBrushColor = Color.BLACK;    this.currentFont = new Font("Times New Roman", Font.PLAIN, 12);    // Determine the initial size and zoom factor of the window.    // If the window is too big, rescale it and zoom out.    int shrinkfactor = 1;    if (sizeX > MAX_WINDOW_X) {      shrinkfactor = (sizeX + MAX_WINDOW_X - 1) / MAX_WINDOW_X;    }    if (sizeY / shrinkfactor > MAX_WINDOW_Y) {      shrinkfactor = (sizeY + MAX_WINDOW_Y - 1) / MAX_WINDOW_Y;    }    winSizeX = sizeX / shrinkfactor;    winSizeY = sizeY / shrinkfactor;    double initialScalingfactor = 1.0 / shrinkfactor;    if (winSizeX > canvasSizeX || winSizeY > canvasSizeY) {      initialScalingfactor = Math.min(1.0 * winSizeX / canvasSizeX,                                      1.0 * winSizeY / canvasSizeY);    }    // Setup the actual window (its size, camera, title, etc.)    if (canvas == null) {      canvas = new PCanvas();      getContentPane().add(canvas, BorderLayout.CENTER);    }    layer = canvas.getLayer();    canvas.setBackground(Color.BLACK);    // Disable anitaliasing to make the lines more visible.    canvas.setDefaultRenderQuality(PPaintContext.LOW_QUALITY_RENDERING);    setLayout(new BorderLayout());    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);    validate();    canvas.requestFocus();    // Manipulation of Piccolo's scene graph should be done from Swings    // event dispatch thread since Piccolo is not thread safe. This code calls    // initialize() from that thread once the PFrame is initialized, so you are    // safe to start working with Piccolo in the initialize() method.    SwingUtilities.invokeLater(new Runnable() {      public void run() {        repaint();      }    });    setSize(winSizeX, winSizeY);    setLocation(posX, posY);    setTitle(name);    // Add a Scrollpane to be able to scroll within the canvas    PScrollPane scrollPane = new PScrollPane(canvas);    getContentPane().add(scrollPane);    scrollPane.setWheelScrollingEnabled(false);    PCamera lc = canvas.getCamera();    lc.scaleViewAboutPoint(initialScalingfactor, 0, 0);    // Disable the default event handlers and add our own.    addWindowListener(svEventHandler);    canvas.removeInputEventListener(canvas.getPanEventHandler());    canvas.removeInputEventListener(canvas.getZoomEventHandler());    canvas.addInputEventListener(svEventHandler);    canvas.addKeyListener(svEventHandler);    // Make the window visible.    validate();    setVisible(true);  }  /**   * Convenience function to add a message box to the window which can be used   * to output debug information.   */  public void addMessageBox() {    if (ta == null) {      ta = new TextArea();      ta.setEditable(false);      getContentPane().add(ta, BorderLayout.SOUTH);    }    // We need to make the window bigger to accomodate the message box.    winSizeY += DEF_MESSAGEBOX_HEIGHT;    setSize(winSizeX, winSizeY);  }  /**   * Allows you to specify the thickness with which to draw lines, recantgles   * and ellipses.   * @param width The new thickness.   */  public void setStrokeWidth(float width) {    // If this worked we wouldn't need the antialiased rendering off.    // stroke = new PFixedWidthStroke(width);    stroke = new BasicStroke(width);  }  /**   * Draw an ellipse at (x,y) with given width and height, using the   * current stroke, the current brush color to fill it and the   * current pen color for the outline.   */  public void drawEllipse(int x, int y, int width, int height) {    PPath pn = PPath.createEllipse(x, y, width, height);    pn.setStrokePaint(currentPenColor);    pn.setStroke(stroke);    pn.setPaint(currentBrushColor);    layer.addChild(pn);  }  /**   * Draw the image with the given name at (x,y). Any image loaded stays in

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?