// 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 / canvasSiz
- 1
- 2
- 3
- 4
- 5
- 6
前往页