📄 viewer.java
字号:
package uk.ac.leeds.ccg.geotools;
import java.awt.*;
import java.util.*;
import uk.ac.leeds.ccg.widgets.*;
import uk.ac.leeds.ccg.geotools.projections.*;
import com.sun.java.util.collections.TreeMap;
/**
* Viewer is a medium for displaying geographic maps in applets and applications.
* The map to display is built up from information stored in a number of thmes.<p>
*
* To construct a working viewer you need to understand how to construct themes
* and layers, a task that will be made easer over time as more helper classes are
* writen.<p>
*
* A viewer has the ability to build up a scaled image from upto three parts
* 1)any number of static themes - not animated at all
* 2)a sequence of single static themes
* 3)animated themes
*
*
* @author James Macgill
* @author Ian Turton
* @version 0.8.0
* GeoTools is a Java class library for developing interactive mapping applets and applications.
* Copyright (C) 1999 James Macgill, Ian Turton.
*
* This file along with the whole GeoTools library is available under the GNU LGPL
*
* You can contact the author at
* James Macgill
* Center for Computational Geography
* School of Geography
* Leeds University
* Leeds
* W.Yorkshire
* UK
* LS2 9JT
*
* j.macgill@geog.leeds.ac.uk
*
* Thanks to Joachim Br鯿kl (saltag) for bug fixes
*/
public class Viewer extends java.awt.Component implements ScaleChangedListener,ThemeChangedListener {
/**
* Version information
*/
public static final String cvsid = "$Id: Viewer.java,v 1.38.4.1 2002/02/15 13:23:21 jmacgill Exp $";
/**
* Constants that represent the different tool modes for a viewer
*/
public static final int ZOOM=0,PAN=1,NAVIGATE=2,SELECT=3;
public Dimension pd= new Dimension(50,50),maxd,mind= new Dimension(50,50);
/**
* The current tool mode for the viewer
*/
//private int toolMode = ZOOM;
/**
* The current tool
*/
private Tool tool;
private Graphics toolGraphics;
/**
* Scaler responsible for converting realworld values to scale
*/
public Scaler scale;
/**
* keep count of how many themes we are displaying
*/
private int themeCount = 0;
private final boolean debug=false;
String name="Un-named Viewer ";
/**
* Used to store an image of the compleated scaled map sections
* Buffer, Holds full image before display.<br>
* static holds the static unchanging themes.<br>
* sequence is for an animated section.<br>
* pan if for smooth paning of the image.<br>
* selection is experimental but is for speeding up selections.
*/
private transient Image screenBuffer,staticBuffer,sequenceBuffer[],panBuffer,selectionBuffer;
/**
* A vector containing all the static themes in this viewer
*/
private Vector staticThemes = new Vector();
/**
* A vector containing all the static themes to draw
*/
private Vector visibleThemes = new Vector();
/**
* An array of themes that make up the sequence part of the display.
*/
private Theme sequenceTheme[],animationTheme;
/**
* A record of the last known size of this component
* Used to check for changes in the dimentions of commponent
*/
//private Rectangle last_size;
/**
* used to track the current status of the mouse.
* It contains info on the curent mouse position (in screen, projection and geographic space)
* as well as details of the last drag operation (start and end point in all three systems)
*/
private MouseStatus mouseStatus;
/**
* geoRectangle bounding box that will hold all layers
*/
private GeoRectangle fullMapExtent = new GeoRectangle();
/**
* Notes wheter the backdrop has been set up yet
*/
private boolean displaying = false;
/**
* Stores the current frame number for the sequence buffer
*/
private int frame = 0;
/**
* highlighting modes
* INSTANT = As mouse moves around screen
* now on REQUEST by default;
*/
public final static int INSTANT = 0;
/**
* highlighting modes
* REQUEST = As mouse clicks on object
* now on REQUEST by default;
*/
public final static int REQUEST = 1;
/**
* Holds the highlighting mode
* INSTANT = As mouse moves around screen
* REQUEST = As mouse clicks on object
* now on INSTANT by default;
*/
private int highlightMode = INSTANT;
/**
* Holds the ID of the object currently under the pointer
*/
private int currentID = 0;
/**
* Holds all of the listeners for ID changed events
*/
private Vector listeners = new Vector();
/**
* Holds all of the click Listeners
*/
private Vector clickedListeners = new Vector();
/**
*Holds the composition listeners
*/
private Vector compositionChangedListeners = new Vector();
/**
* Holds all the highlight position change listeners
*/
private Vector hpcListeners = new Vector();
/**
* Holds all the selection position change listeners
*/
private Vector spcListeners = new Vector();
/**
* Holds all the selection region change listeners
*/
private Vector srcListeners = new Vector();
private SelectionRegionChangedListener srcFinal = null;
/**
* Hoads a flag for each frame in the sequence buffer to say
* if it is up-to-date or not
*/
private boolean sequenceFrameValid[];
/**
* Notes if the selection has changed since the last repaint
*/
private boolean selectionChanged = true;
/**
* Holds the last know size of the viewer
* as a check for when it changes
*/
private Rectangle lastSize = new Rectangle();
private boolean showTips = true;
//private MouseIdle mouseIdle;
//private boolean mouseStill = true;
protected int timeout = 250;
protected ThemeStack themeStack = new ThemeStack();
public Viewer() {
this(true);
}
/**
* Default constructor for a viewer.
* Sets up and initalises a new viewer, it won't do much however
* untill it has at least one theme added to it.
* @see addTheme
* @see addSaticTheme
* @see addSequenceTheme
*/
public Viewer(boolean activeMouse) {
if(debug)System.out.println("---->uk.ac.leeds.ccg.geotools.Viewer constructed, will identify itself as V--->");
if(debug)System.out.println("V--->Viewer Started");
//last_size = new Rectangle();
//last_size.add(this.getBounds());
mouseStatus = new MouseStatus(this);
setTool(new ZoomTool());
scale = new Scaler(fullMapExtent,this.getBounds());
if(activeMouse){
ViewerMouse aViewerMouse = new ViewerMouse();
this.addMouseListener(aViewerMouse);
ViewerMouseMotion aViewerMouseMotion = new ViewerMouseMotion();
this.addMouseMotionListener(aViewerMouseMotion);
ComponentAdapt adapt = new ComponentAdapt();
this.addComponentListener(adapt);
}
}
public void addTheme(Theme t,int waight){
addStaticTheme(t,waight);
}
/**
* Add a new theme.
* There is some duplicatin here as addTheme simply calls addStaticTheme
*/
public void addTheme(Theme t){
addStaticTheme(t,0);
}
public Dimension getPreferredSize(){
if(debug)System.out.println("V--->"+name+"Pref "+pd.width+" "+pd.height);
return pd;
}
public Dimension getMinimumSize(){
// System.out.println("V--->"+name+"Min "+mind.width+" "+mind.height);
if(debug)System.out.println("V--->Min size called");
return mind;
}
public Dimension getMaximumSize(){
if(debug)System.out.println("V--->"+name+"Max "+maxd.width+" "+maxd.height);
return maxd;
}
public void setPreferredSize(Dimension d){
if(debug)System.out.println("V--->"+name+"Pref "+d.width+" "+d.height);
pd=d;
}
public void setMinimumSize(Dimension d){
if(debug)System.out.println("V--->"+name+"Min "+d.width+" "+d.height);
mind=d;
}
public void setMaximumSize(Dimension d){
if(debug)System.out.println("V--->"+name+"Max "+d.width+" "+d.height);
maxd=d;
}
public void setBounds(int x,int y,int w,int h){
if (w >= 0 && h >= 0) {
super.setBounds(x,y,w,h);
pd=new Dimension(w,h);
mind=new Dimension(w,h);
maxd=new Dimension(w,h);
}
}
/**
* Remove a theme
*/
public void removeTheme(Theme t){
removeStaticTheme(t);
themeStack.removeTheme(t);
}
public void removeStaticTheme(Theme t){
if(visibleThemes.contains(t)){visibleThemes.removeElement(t);}
if(staticThemes.contains(t)){
staticThemes.removeElement(t);
removeHighlightPositionChangedListener(t);
removeSelectionPositionChangedListener(t);
removeSelectionRegionChangedListener(t);
themeStack.removeTheme(t);
themeCount--;
updateStaticBuffer();
}
notifyCompositionChanged(CompositionChangedEvent.REMOVED);
}
/**
* Add an array of themes
* These can then be steped through in sequence
* or displayed on request
* @param t[] an array of themes
*/
public void setSequenceTheme(Theme t[]){
if(sequenceTheme==null){themeCount++;}
createSequenceBuffer(t.length);
sequenceTheme = t;
//add all the themes to list of highlight position changed listeners
for(int i = 0;i<t.length;i++){
//addHighlightPositionChangedListener(t[i]);
t[i].addThemeChangedListener(this);
if(debug)System.out.println("V--->"+name+"Adding a theme to Bounds\n"+
fullMapExtent);
fullMapExtent.add(t[i].getBounds());
if(debug)System.out.println("V--->"+name+"Added a theme to Bounds\n"+
fullMapExtent);
}
if(themeCount==1){
setupScale();
}
/*updateSequenceBuffer();*/
invalidateSequenceBuffer();
}
/**
* Selects witch of the sequence frames to display
*/
public void setSequenceFrame(int f){
frame = f;
if(debug)System.out.println("V--->Frame set to"+f);
//map_point = new GeoPoint(map_xy[0],map_xy[1]);
sequenceTheme[frame].setHighlight(mouseStatus.map_point);
update(this.getGraphics());
}
/**
* adds the theme that will be used to hold any animations
*/
public void setAnimationTheme(Theme t){
if(animationTheme!=null){
animationTheme.removeThemeChangedListener(this);
}
animationTheme = t;
if(animationTheme!=null){
t.addThemeChangedListener(this);
}
}
/**
* used internaly to create the sequence buffer
*/
private void createSequenceBuffer(int size){
if(getBounds().width==0||this.createImage(getBounds().width,getBounds().height)==null){
//throw an exception ???
//throw(new Error("viewers MUST be added to a peer (like applet or frame etc. before they can be used)"));
return;
}
sequenceBuffer = new Image[size];
sequenceFrameValid = new boolean[size];
for(int i = 0;i<size;i++){
sequenceBuffer[i] = this.createImage(getBounds().width,getBounds().height);
sequenceFrameValid[i] = false;
}
}
/**
* set whether highlights are done instantly or on request
* viewer.INSTANT / viewer.REQUEST
*/
public void setHighlightMode(int flag){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -