Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jplot/GraphLabel.java


1   /*
2    * JPLOT  -- Java Plotting Interface for any programme or
3    *           as an independent GUI
4    * 
5    * Copyright (C) 1999-2000 Jan van der Lee
6    *
7    * This program is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation; either version 2
10   * of the License, or (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  
20   * 02111-1307, USA.
21   *
22   * Send bugs, suggestions or queries to <jplot@cig.ensmp.fr>
23   * The latest releases are found at 
24   * http://www.cig.ensmp.fr/~vanderlee/jplot.html
25   *
26   * Initally developed for use by the Centre d'Informatique Geologique 
27   * Ecole des Mines de Paris, Fontainebleau, France.
28   */
29  
30  package jplot;
31  
32  import java.awt.font.*;
33  import java.awt.*;
34  import java.text.*;
35  import javax.swing.*;
36  import java.util.*;
37  import java.io.*;
38  
39  /**
40   * This class defines a label in terms of the actual text, font, color
41   * and position but also stuff like rotation, whether to hide or show etc.
42   * Some special treatment for standard X, Y labels and a title. Random labels
43   * are considered to be of type OTHER, which places them, by default, in the
44   * lower-left corner of the graph. 
45   *
46   * Extends Rectangle, since a label has a rectangular bounding box,
47   * used to select, drag and drop the label. Note that the bounding box
48   * is defined by the upper-left corner, width (to the right) and
49   * height (directed towards the bottom).  
50   */
51  public class GraphLabel {
52  
53    static final int UNKNOWN=-1;
54    static final int XLABEL=0;    // X label for a 2D graph
55    static final int YLABEL=1;    // Y label for a 2D graph
56    static final int TITLE=2;     // title for a 2D graph
57    static final int PIPER_X1=3;  // first X label for a piper diagram
58    static final int PIPER_X2=4;  // second X label for a piper diagram
59    static final int PIPER_Y1=5;  // lower-left Y label for a piper diagram
60    static final int PIPER_Y2=6;  // lower-right Y label for a piper diagram
61    static final int PIPER_Y3=7;  // upper-left Y label for a piper diagram
62    static final int PIPER_Y4=8;  // upper-right Y label for a piper diagram
63    static final int DATA=9;      // labels defined by the data x,y coordinates
64    static final int OTHER=10;    // random labels
65    static final int CHECK=11;    // DATA labels which must be checked
66  
67  
68    private String text;
69    private Font font;
70    private Color color;
71    private boolean active;
72    private boolean usePos;
73    private FontMetrics fm;
74    private double rotation;
75    private int whoAmI;
76    private double xPos;   // x-position of the text
77    private double yPos;   // y-position of the text
78    private double bbX;    // x-position of the bounding box
79    private double bbY;    // x-position of the bounding box
80    private double textWidth;
81    private double textHeight;
82    private double bbWidth;
83    private double bbHeight;
84    private double sin,cos;
85    private AttributedString attributedString;
86    private File file;    // label belongs to this file
87    private boolean hideLabel;
88  
89    private final String lf = System.getProperty("line.separator");
90  
91    /**
92     * Constructor, sets the text of the label.
93     * @param t type of this label
94     * @param s text of the label
95     * @param f font of the label
96     * @param c text color of the label
97     */
98    public GraphLabel(int t, String s, Font f, Color c) {
99      font = f;
100     color = c;
101     usePos = false;
102     active = false;
103     rotation = 0.0;
104     sin = 0.0;
105     hideLabel = false;
106     cos = 1.0;
107     xPos = yPos = 0.0;
108     bbX = bbY = 0.0;
109     bbWidth = bbHeight = 0.0;
110     file = null;
111     setID(t);    // might change rotate if it is an YLABEL
112     setFont(f);  
113     setText(s); // should be at the end
114   }
115 
116   /*
117    * Sets the size of the bounding box.
118    * Note that this doesn't work perfectly well since rotated text 
119    * is set closer together, at least in the current jvm (1.3).
120    * Hence we have to introduce some ugly empirical corrections.
121    */
122   private void setBoundingBox() {
123     if (rotation != 0.0) {
124       setSize(textWidth*cos + textHeight*sin,
125         textHeight*cos + textWidth*sin);
126     }
127     else setSize(textWidth,textHeight);
128   }
129 
130   /*
131    * Determine the font metrics of the current text.
132    * Wouldn't it be nice if I could get the font-metrics of 
133    * the text *without* this ugly memory allocation???
134    */
135   private void setTextMetrics() {
136     if (text != null && !text.equals("")) {
137       attributedString = new AttributedString(text);
138       attributedString.addAttribute(TextAttribute.FONT,font);
139       if (fm == null) fm = (new JPanel()).getFontMetrics(font);
140       textWidth = fm.stringWidth(text);
141       textHeight = fm.getHeight();
142       setBoundingBox();
143     }
144     else textWidth = textHeight = 0.0;
145   }
146 
147   /**
148    * Constructor, sets the text of the label.
149    * @param s new text of the label
150    */
151   public GraphLabel(int t, String s) {
152     this(t,s,Utils.getDefaultFont(),Color.black);
153   }
154 
155   /**
156    * Constructor, sets the text of the label.
157    * @param s new text of the label
158    */
159   public GraphLabel(String s) {
160     this(UNKNOWN,s);
161   }
162 
163   /**
164    * Constructor, sets the ID of the label but no text.
165    * @param t ID of the label
166    */
167   public GraphLabel(int t) {
168     this(t,"");
169   }
170 
171   /**
172    * Constructor, does nothing but initializing.
173    */
174   public GraphLabel() {
175     this("");
176   }
177 
178   /**
179    * Constructor, builds the class with another graph label.
180    */
181   public GraphLabel(GraphLabel gl) {
182     copy(gl);
183   }
184 
185  /**
186    * Constructor, builds the class with another graph label.
187    */
188   public void copy(GraphLabel gl) {
189     bbX = gl.getX();
190     bbY = gl.getY();
191     bbWidth = gl.getWidth();
192     bbHeight = gl.getHeight();
193     active = gl.isActive();
194     usePos = gl.usePosition();
195     setRotation(gl.getRotation());
196     setID(gl.getID());
197     hideLabel = gl.hide();
198     xPos = gl.getXPos();
199     yPos = gl.getYPos();
200     textWidth = gl.getTextWidth();
201     textHeight = gl.getTextHeight();
202     file = gl.getFile();
203     setFont(new Font(gl.getFont().getName(),
204          gl.getFont().getStyle(),gl.getFont().getSize()));
205     color = new Color(gl.getColor().getRed(),
206           gl.getColor().getGreen(),gl.getColor().getBlue());
207     setText(gl.getText());
208   }
209 
210   /**
211    * Sets the text of the label to something new.
212    * @param s new text for the label
213    */
214   public void setText(String s) {
215     text = s;
216     setTextMetrics();
217     setLocation(bbX,bbY);
218   }
219 
220   /**
221    * @returns the current text of the label
222    */
223   public String getText() {
224     return text;
225   }
226 
227   /**
228    * @returns an attributedCharacterIterator instance of the
229    * current text
230    */
231   public AttributedCharacterIterator getCharIterator() {
232     return attributedString.getIterator();
233   }
234 
235   /**
236    * Sets the color to a specific value
237    * @param c color used to draw the label
238    */
239   public void setColor(Color c) {
240     color = c;
241   }
242 
243   /**
244    * @return the color used to draw the label
245    */
246   public Color getColor() {
247     return color;
248   }
249 
250   /**
251    * Sets the font to a specific value
252    * @param f font used to draw the label
253    */
254   public void setFont(Font f) {
255     font = f;
256     fm = (new JPanel()).getFontMetrics(font);
257     setTextMetrics();
258   }
259 
260   /**
261    * Sets the font to a specific value
262    * @return the font used to draw the label
263    */
264   public Font getFont() {
265     return font;
266   }
267 
268   /**
269    * @param b true if the user starts to draw the label
270    */
271   public void setActive(boolean b) {
272     active = b;
273   }
274 
275   /**
276    * @return true if the label is actually being drawn by the mouse
277    */
278   public boolean isActive() {
279     return active;
280   }
281 
282   /**
283    * Allows the user to used the current x- and y-positions,
284    * will use default positions otherwise
285    * @param b true if the positions should be used
286    */
287   public void setUsePosition(boolean b) {
288     usePos = b;
289   }
290 
291   /**
292    * @return true if the positions should be used
293    */
294   public boolean usePosition() {
295     return usePos;
296   }
297 
298   /**
299    * @return true if we should hide this label (do not show)
300    */
301   public boolean hide() {
302     return hideLabel;
303   }
304 
305   /**
306    * sets the hide attribute of this label
307    * @param h flag, true if the label should'nt show
308    */
309   public void hide(boolean h) {
310     hideLabel = h;
311   }
312   
313   /**
314    * returns true if the current label corresponds to one of
315    * the pre-defined label types (X-label, Y-label etc).
316    * @param type type to compare with (must be an int)
317    * @return true if 'type' corresponds to the current 'whoAmI'
318    */
319   public boolean equals(int type) {
320     return (type == whoAmI);
321   }
322 
323   /**
324    * returns true if the current label corresponds to one of
325    * the pre-defined label types (X-label, Y-label etc).
326    * @param name name to compare with (must be a string)
327    * @return true if 'name' corresponds to the current label text
328    */
329   public boolean equals(String name) {
330     return text.equals(name);
331   }
332 
333   /**
334    * Sets the current identity of the label to some specific value
335    * The idientity must be an int and, in principle, something predefined 
336    * such as GraphLabel.XLABEL).
337    * @param type type of the current label
338    */
339   public void setID(int type) {
340     whoAmI = type;
341   }
342 
343   /**
344    * @return the current identity of the label to some specific value.
345    */
346   public int getID() {
347     return whoAmI;
348   }
349 
350   /**
351    * Sets the rotation angle.
352    * @param r angle for this label
353    */
354   public void setDataRotation(double r) {
355     rotation = r;
356   }
357 
358   /**
359    * Sets the rotation angle. Although all kind of angles (in PI-units)
360    * are allowed, internally we only use the interval 0-2pi hence we
361    * take care of all other cases.
362    * @param r angle for this label
363    */
364   public void setRotation(double r) {
365     rotation = r;
366     while (rotation < 0.0) rotation += 2.0*Math.PI;
367     while (rotation > 2.0*Math.PI) rotation -= 2.0*Math.PI;
368     if (rotation != 0.0) {
369       sin = Math.abs(Math.sin(rotation));
370       cos = Math.abs(Math.cos(rotation));
371     }
372     else {
373       sin = 0.0;
374       cos = 1.0;
375     }
376     setBoundingBox();
377     setLocation(bbX,bbY);
378   }
379 
380   /**
381    * Returns the rotation angle.
382    * @return angle for this label
383    */
384   public double getRotation() {
385     return rotation;
386   }
387 
388   /**
389    * This function also sets the text location of the label text
390    * itself, slightly different from the x,y position of the box.
391    * Optimize this function since it is used for drag'n drop.
392    *
393    * @param x x-position of the lower-left corner of the text
394    * @param y y-position of the lower-left corner of the text
395    */
396   public void setLocation(double x, double y) {
397     bbX = x;
398     bbY = y;
399     if (rotation <= Math.PI/2.0) {
400       xPos = x;
401       yPos = y + textHeight*cos;
402     }
403     else if (rotation <= Math.PI) {
404       xPos = x + getWidth() - textHeight*sin;
405       yPos = y;
406     }
407     else if (rotation <= 3.0*Math.PI/2.0) {
408       xPos = x + getWidth() - textHeight*sin;
409       yPos = y + getHeight() - textHeight*cos;
410     }
411     else if (rotation <= 2.0*Math.PI) {
412       xPos = x + textHeight*sin;
413       yPos = y + getHeight();
414     }
415   }
416 
417   /**
418    * Sets the location of this label in data coordinates.
419    * Ones set this way, you cannot plot the label, it must first
420    * define the location in pixel-coordinates (setLocation(x,y));
421    * @param x x-position of the lower-left corner of the text
422    * @param y y-position of the lower-left corner of the text
423    */
424   public void setDataLocation(double x, double y) {
425     xPos = x;
426     yPos = y;
427   }
428 
429   /**
430    * Returns the X position of the text.
431    * @return the x-position of the text
432    */
433   public double getXPos() {
434     return xPos;
435   }
436 
437   /**
438    * Returns the Y position of the text.
439    * @return the y-position of the text
440    */
441   public double getYPos() {
442     return yPos;
443   }
444 
445   /**
446    * Returns the X position of the bounding box.
447    * @return the x-position of the bounding box
448    */
449   public double getX() {
450     return bbX;
451   }
452 
453   /**
454    * Returns the Y position of the bounding box.
455    * @return the y-position of the bounding box
456    */
457   public double getY() {
458     return bbY;
459   }
460 
461   /**
462    * Sets the size of the bounding box:
463    * @param w width of the bb
464    * @param h height of the bb
465    */
466   public void setSize(double w, double h) {
467     bbWidth = w;
468     bbHeight = h;
469   }
470 
471   /**
472    * Sets the size of the text-label:
473    * @param w width of the label
474    * @param h height of the label
475    */
476   public void setTextSize(double w, double h) {
477     textWidth = w;
478     textHeight = h;
479   }
480 
481   /**
482    * Returns the width of the bounding box of the label
483    * @return the width of the bounding box
484    */
485   public double getWidth() {
486     return bbWidth;
487   }
488 
489   /**
490    * Returns the height of the bounding box of the label
491    * @return the height of the bounding box
492    */
493   public double getHeight() {
494     return bbHeight;
495   }
496 
497   /**
498    * Returns the width of the text of the label
499    * @return the width of the text
500    */
501   public double getTextWidth() {
502     return textWidth;
503   }
504 
505   /**
506    * Returns the height of the text of the label
507    * @return the height of the text
508    */
509   public double getTextHeight() {
510     return textHeight;
511   }
512 
513   /**
514    * @return the file to which the label belongs
515    */
516   public File getFile() {
517     return file;
518   }
519 
520   /**
521    * Sets the file to which the label belongs. Can be null.
522    * @param f file to which the label belongs
523    */
524   public void setFile(File f) {
525     file = f;
526   }
527 
528   /**
529    * @return a string representation of this label, the text.
530    */
531   public String toString() {
532     return text;
533   }
534 
535   /**
536    * Checks whether x,y falls within the bounding box of the
537    * current text.
538    * @param x x-position
539    * @param y y-position
540    * @return true if the point x,y falls withing the bounding box.
541    */
542   public boolean contains(double x, double y) {
543     return (x>bbX && x<bbX+bbWidth &&  y>bbY && y<bbY+bbHeight);
544   }
545 
546   /**
547    * Returns the settings of the current label in a string.
548    * Calling this method creates a string containing the name
549    * and settings of the current label in string-format, formatted
550    * such that it can directly be used for a script file.
551    * @return the settings of the current label in a string.
552    */
553   public String getSettings() {
554     StringBuffer sb = new StringBuffer(200);
555     sb.append(lf);
556     sb.append("    label \"" + text + "\" {");
557     sb.append(lf);
558     sb.append("      whoami = ").append(whoAmI);
559     sb.append(lf);
560     sb.append("      color = ").append(color.getRed()).append(",");
561     sb.append(color.getGreen()).append(",").append(color.getBlue());
562     sb.append(lf);
563     sb.append("      font ").append(" = \"").append(font.getName()).append("\",");
564     sb.append(font.getStyle()).append(",").append(font.getSize());
565     if (usePos) {
566       sb.append(lf);
567       sb.append("      location = ").append((int)bbX).append(",");
568       sb.append((int)bbY);
569     }
570     sb.append(lf);
571     sb.append("      rotation = ").append(rotation/Math.PI*180.0);
572     sb.append(lf).append("    }");
573     return sb.toString();
574   }
575   
576 }