Statistics
| Revision:

root / trunk / extensions / extRemoteSensing / src / org / gvsig / remotesensing / scatterplot / chart / ScatterPlotDiagram.java @ 17400

History | View | Annotate | Download (79.5 KB)

1
package org.gvsig.remotesensing.scatterplot.chart;
2

    
3
import java.awt.AWTEvent;
4
import java.awt.Color;
5
import java.awt.Dimension;
6
import java.awt.Graphics;
7
import java.awt.Graphics2D;
8
import java.awt.Image;
9
import java.awt.Insets;
10
import java.awt.Point;
11
import java.awt.Shape;
12
import java.awt.event.ActionEvent;
13
import java.awt.event.ActionListener;
14
import java.awt.event.MouseEvent;
15
import java.awt.event.MouseListener;
16
import java.awt.event.MouseMotionListener;
17
import java.awt.geom.AffineTransform;
18
import java.awt.geom.Line2D;
19
import java.awt.geom.Point2D;
20
import java.awt.geom.Rectangle2D;
21
import java.awt.print.PageFormat;
22
import java.awt.print.Printable;
23
import java.awt.print.PrinterException;
24
import java.awt.print.PrinterJob;
25
import java.io.File;
26
import java.io.IOException;
27
import java.io.Serializable;
28
import java.util.EventListener;
29
import java.util.Iterator;
30
import java.util.ResourceBundle;
31

    
32
import javax.swing.JFileChooser;
33
import javax.swing.JMenu;
34
import javax.swing.JMenuItem;
35
import javax.swing.JOptionPane;
36
import javax.swing.JPanel;
37
import javax.swing.JPopupMenu;
38
import javax.swing.SwingUtilities;
39
import javax.swing.ToolTipManager;
40
import javax.swing.event.EventListenerList;
41

    
42
import org.jfree.chart.ChartMouseEvent;
43
import org.jfree.chart.ChartMouseListener;
44
import org.jfree.chart.ChartRenderingInfo;
45
import org.jfree.chart.ChartUtilities;
46
import org.jfree.chart.JFreeChart;
47
import org.jfree.chart.entity.ChartEntity;
48
import org.jfree.chart.entity.EntityCollection;
49
import org.jfree.chart.event.ChartChangeEvent;
50
import org.jfree.chart.event.ChartChangeListener;
51
import org.jfree.chart.event.ChartProgressEvent;
52
import org.jfree.chart.event.ChartProgressListener;
53
import org.jfree.chart.plot.Plot;
54
import org.jfree.chart.plot.PlotOrientation;
55
import org.jfree.chart.plot.PlotRenderingInfo;
56
import org.jfree.chart.plot.Zoomable;
57
import org.jfree.data.Range;
58
import org.jfree.ui.ExtensionFileFilter;
59

    
60
import com.iver.andami.PluginServices;
61

    
62

    
63
public class ScatterPlotDiagram extends JPanel implements ChartChangeListener,
64
        ChartProgressListener, ActionListener, MouseListener, 
65
        MouseMotionListener, Printable, Serializable {
66

    
67
    /** For serialization. */
68
    private static final long serialVersionUID = 6046366297214274674L;
69
    
70
    /** Default setting for buffer usage. */
71
    public static final boolean DEFAULT_BUFFER_USED = false;
72

    
73
    /** The default panel width. */
74
    public static final int DEFAULT_WIDTH = 680;
75

    
76
    /** The default panel height. */
77
    public static final int DEFAULT_HEIGHT = 420;
78

    
79
    /** The default limit below which chart scaling kicks in. */
80
    public static final int DEFAULT_MINIMUM_DRAW_WIDTH = 300;
81

    
82
    /** The default limit below which chart scaling kicks in. */
83
    public static final int DEFAULT_MINIMUM_DRAW_HEIGHT = 200;
84

    
85
    /** The default limit below which chart scaling kicks in. */
86
    public static final int DEFAULT_MAXIMUM_DRAW_WIDTH = 800;
87

    
88
    /** The default limit below which chart scaling kicks in. */
89
    public static final int DEFAULT_MAXIMUM_DRAW_HEIGHT = 600;
90

    
91
    /** The minimum size required to perform a zoom on a rectangle */
92
    public static final int DEFAULT_ZOOM_TRIGGER_DISTANCE = 10;
93

    
94
    /** Properties action command. */
95
    public static final String PROPERTIES_COMMAND = "PROPERTIES";
96

    
97
    /** Save action command. */
98
    public static final String SAVE_COMMAND = "SAVE";
99

    
100
    /** Print action command. */
101
    public static final String PRINT_COMMAND = "PRINT";
102

    
103
    /** Zoom in (both axes) action command. */
104
    public static final String ZOOM_IN_BOTH_COMMAND = "ZOOM_IN_BOTH";
105

    
106
    /** Zoom in (domain axis only) action command. */
107
    public static final String ZOOM_IN_DOMAIN_COMMAND = "ZOOM_IN_DOMAIN";
108

    
109
    /** Zoom in (range axis only) action command. */
110
    public static final String ZOOM_IN_RANGE_COMMAND = "ZOOM_IN_RANGE";
111

    
112
    /** Zoom out (both axes) action command. */
113
    public static final String ZOOM_OUT_BOTH_COMMAND = "ZOOM_OUT_BOTH";
114

    
115
    /** Zoom out (domain axis only) action command. */
116
    public static final String ZOOM_OUT_DOMAIN_COMMAND = "ZOOM_DOMAIN_BOTH";
117

    
118
    /** Zoom out (range axis only) action command. */
119
    public static final String ZOOM_OUT_RANGE_COMMAND = "ZOOM_RANGE_BOTH";
120

    
121
    /** Zoom reset (both axes) action command. */
122
    public static final String ZOOM_RESET_BOTH_COMMAND = "ZOOM_RESET_BOTH";
123

    
124
    /** Zoom reset (domain axis only) action command. */
125
    public static final String ZOOM_RESET_DOMAIN_COMMAND = "ZOOM_RESET_DOMAIN";
126

    
127
    /** Zoom reset (range axis only) action command. */
128
    public static final String ZOOM_RESET_RANGE_COMMAND = "ZOOM_RESET_RANGE";
129
    
130
    
131
    /** Definicion de nueva Roi **/
132
    public static final String NEW_CLASS_COMMAND ="NEW_CLASS";
133
    
134
    
135
    /** Borrado de las Rois sobre el grafico **/
136
    public static final String CLEAR_CHART ="CLEAR_CHART";
137
    
138
 
139
    
140
    /**Contador de Rois definidas para el diagrama*/
141
    int contador= 0;
142
    
143
    
144

    
145
    /** The chart that is displayed in the panel. */
146
    private JFreeChart chart;
147

    
148
    /** Storage for registered (chart) mouse listeners. */
149
    private EventListenerList chartMouseListeners;
150

    
151
    /** A flag that controls whether or not the off-screen buffer is used. */
152
    private boolean useBuffer;
153

    
154
    /** A flag that indicates that the buffer should be refreshed. */
155
    private boolean refreshBuffer;
156

    
157
    /** A buffer for the rendered chart. */
158
    private Image chartBuffer;
159

    
160
    /** The height of the chart buffer. */
161
    private int chartBufferHeight;
162

    
163
    /** The width of the chart buffer. */
164
    private int chartBufferWidth;
165

    
166
    /** 
167
     * The minimum width for drawing a chart (uses scaling for smaller widths). 
168
     */
169
    private int minimumDrawWidth;
170

    
171
    /** 
172
     * The minimum height for drawing a chart (uses scaling for smaller 
173
     * heights). 
174
     */
175
    private int minimumDrawHeight;
176

    
177
    /** 
178
     * The maximum width for drawing a chart (uses scaling for bigger 
179
     * widths). 
180
     */
181
    private int maximumDrawWidth;
182

    
183
    /** 
184
     * The maximum height for drawing a chart (uses scaling for bigger 
185
     * heights). 
186
     */
187
    private int maximumDrawHeight;
188

    
189
    /** The popup menu for the frame. */
190
    private JPopupMenu popup;
191

    
192
    /** The drawing info collected the last time the chart was drawn. */
193
    private ChartRenderingInfo info;
194
    
195
    /** The chart anchor point. */
196
    private Point2D anchor;
197

    
198
    /** The scale factor used to draw the chart. */
199
    private double scaleX;
200

    
201
    /** The scale factor used to draw the chart. */
202
    private double scaleY;
203

    
204
    /** The plot orientation. */
205
    private PlotOrientation orientation = PlotOrientation.VERTICAL;
206
    
207
    /** A flag that controls whether or not domain zooming is enabled. */
208
    private boolean domainZoomable = false;
209

    
210
    /** A flag that controls whether or not range zooming is enabled. */
211
    private boolean rangeZoomable = false;
212

    
213
    /** 
214
     * The zoom rectangle starting point (selected by the user with a mouse 
215
     * click).  This is a point on the screen, not the chart (which may have
216
     * been scaled up or down to fit the panel).  
217
     */
218
    private Point zoomPoint = null;
219

    
220
    /** The zoom rectangle (selected by the user with the mouse). */
221
    private transient Rectangle2D zoomRectangle = null;
222

    
223
    /** Controls if the zoom rectangle is drawn as an outline or filled. */
224
    private boolean fillZoomRectangle = true;
225

    
226
    /** The minimum distance required to drag the mouse to trigger a zoom. */
227
    private int zoomTriggerDistance;
228
    
229
    /** A flag that controls whether or not horizontal tracing is enabled. */
230
    private boolean horizontalAxisTrace = false;
231

    
232
    /** A flag that controls whether or not vertical tracing is enabled. */
233
    private boolean verticalAxisTrace =false;
234

    
235
    /** A vertical trace line. */
236
    private transient Line2D verticalTraceLine;
237

    
238
    /** A horizontal trace line. */
239
    private transient Line2D horizontalTraceLine;
240

    
241
    /** Menu item for zooming in on a chart (both axes). */
242
    private JMenuItem zoomInBothMenuItem;
243

    
244
    /** Menu item for zooming in on a chart (domain axis). */
245
    private JMenuItem zoomInDomainMenuItem;
246

    
247
    /** Menu item for zooming in on a chart (range axis). */
248
    private JMenuItem zoomInRangeMenuItem;
249

    
250
    /** Menu item for zooming out on a chart. */
251
    private JMenuItem zoomOutBothMenuItem;
252

    
253
    /** Menu item for zooming out on a chart (domain axis). */
254
    private JMenuItem zoomOutDomainMenuItem;
255

    
256
    /** Menu item for zooming out on a chart (range axis). */
257
    private JMenuItem zoomOutRangeMenuItem;
258

    
259
    /** Menu item for resetting the zoom (both axes). */
260
    private JMenuItem zoomResetBothMenuItem;
261

    
262
    /** Menu item for resetting the zoom (domain axis only). */
263
    private JMenuItem zoomResetDomainMenuItem;
264

    
265
    /** Menu item for resetting the zoom (range axis only). */
266
    private JMenuItem zoomResetRangeMenuItem;
267

    
268
    /**
269
     * The default directory for saving charts to file.
270
     * 
271
     * @since 1.0.7
272
     */
273
    private File defaultDirectoryForSaveAs;
274
    
275
    /** A flag that controls whether or not file extensions are enforced. */
276
    private boolean enforceFileExtensions;
277

    
278
    /** A flag that indicates if original tooltip delays are changed. */
279
    private boolean ownToolTipDelaysActive;  
280
    
281
    /** Original initial tooltip delay of ToolTipManager.sharedInstance(). */
282
    private int originalToolTipInitialDelay;
283

    
284
    /** Original reshow tooltip delay of ToolTipManager.sharedInstance(). */
285
    private int originalToolTipReshowDelay;  
286

    
287
    /** Original dismiss tooltip delay of ToolTipManager.sharedInstance(). */
288
    private int originalToolTipDismissDelay;
289

    
290
    /** Own initial tooltip delay to be used in this chart panel. */
291
    private int ownToolTipInitialDelay;
292
    
293
    /** Own reshow tooltip delay to be used in this chart panel. */
294
    private int ownToolTipReshowDelay;  
295

    
296
    /** Own dismiss tooltip delay to be used in this chart panel. */
297
    private int ownToolTipDismissDelay;    
298

    
299
    /** The factor used to zoom in on an axis range. */
300
    private double zoomInFactor = 0.5;
301
    
302
    /** The factor used to zoom out on an axis range. */
303
    private double zoomOutFactor = 2.0;
304
    
305
    /**
306
     * A flag that controls whether zoom operations are centred on the
307
     * current anchor point, or the centre point of the relevant axis.
308
     *
309
     * @since 1.0.7
310
     */
311
    private boolean zoomAroundAnchor;
312
    
313
    /** The resourceBundle for the localization. */
314
    protected static ResourceBundle localizationResources 
315
            = ResourceBundle.getBundle("org.jfree.chart.LocalizationBundle");
316

    
317
    
318
    
319
    private ROIChart activeROI= null;
320
    private ROIChartList roiList= new ROIChartList();
321
    Graphics2D g2= null;
322
    
323
    
324
    /**
325
     * Constructs a panel that displays the specified chart.
326
     *
327
     * @param chart  the chart.
328
     */
329
    public ScatterPlotDiagram(JFreeChart chart) {
330

    
331
        this(
332
            chart,
333
            DEFAULT_WIDTH,
334
            DEFAULT_HEIGHT,
335
            DEFAULT_MINIMUM_DRAW_WIDTH,
336
            DEFAULT_MINIMUM_DRAW_HEIGHT,
337
            DEFAULT_MAXIMUM_DRAW_WIDTH,
338
            DEFAULT_MAXIMUM_DRAW_HEIGHT,
339
            DEFAULT_BUFFER_USED,
340
            true,  // properties
341
            true,  // save
342
            true,  // print
343
            true,  // zoom
344
            true   // tooltips
345
        );
346

    
347
    }
348

    
349
   
350

    
351
    /**
352
     * Constructs a JFreeChart panel.
353
     *
354
     * @param chart  the chart.
355
     * @param width  the preferred width of the panel.
356
     * @param height  the preferred height of the panel.
357
     * @param minimumDrawWidth  the minimum drawing width.
358
     * @param minimumDrawHeight  the minimum drawing height.
359
     * @param maximumDrawWidth  the maximum drawing width.
360
     * @param maximumDrawHeight  the maximum drawing height.
361
     * @param useBuffer  a flag that indicates whether to use the off-screen
362
     *                   buffer to improve performance (at the expense of 
363
     *                   memory).
364
     * @param properties  a flag indicating whether or not the chart property
365
     *                    editor should be available via the popup menu.
366
     * @param save  a flag indicating whether or not save options should be
367
     *              available via the popup menu.
368
     * @param print  a flag indicating whether or not the print option
369
     *               should be available via the popup menu.
370
     * @param zoom  a flag indicating whether or not zoom options should be 
371
     *              added to the popup menu.
372
     * @param tooltips  a flag indicating whether or not tooltips should be 
373
     *                  enabled for the chart.
374
     */
375
    public ScatterPlotDiagram(JFreeChart chart,
376
                      int width,
377
                      int height,
378
                      int minimumDrawWidth,
379
                      int minimumDrawHeight,
380
                      int maximumDrawWidth,
381
                      int maximumDrawHeight,
382
                      boolean useBuffer,
383
                      boolean properties,
384
                      boolean save,
385
                      boolean print,
386
                      boolean zoom,
387
                      boolean tooltips) {
388

    
389
        this.setChart(chart);
390
        this.chartMouseListeners = new EventListenerList();
391
        this.info = new ChartRenderingInfo();
392
        setPreferredSize(new Dimension(width, height));
393
        this.useBuffer = useBuffer;
394
        this.refreshBuffer = false;
395
        this.minimumDrawWidth = minimumDrawWidth;
396
        this.minimumDrawHeight = minimumDrawHeight;
397
        this.maximumDrawWidth = maximumDrawWidth;
398
        this.maximumDrawHeight = maximumDrawHeight;
399
        this.zoomTriggerDistance = DEFAULT_ZOOM_TRIGGER_DISTANCE;
400

    
401
        // set up popup menu...
402
        this.popup = null;
403
        if (properties || save || print || zoom) {
404
            this.popup = createPopupMenu(properties, save, print, zoom);
405
        }
406

    
407
        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
408
        enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
409
        setDisplayToolTips(tooltips);
410
        addMouseListener(this);
411
        addMouseMotionListener(this);
412

    
413
        this.defaultDirectoryForSaveAs = null;
414
        this.enforceFileExtensions = true;
415

    
416
        // initialize ChartPanel-specific tool tip delays with
417
        // values the from ToolTipManager.sharedInstance()
418
        ToolTipManager ttm = ToolTipManager.sharedInstance();       
419
        this.ownToolTipInitialDelay = ttm.getInitialDelay();
420
        this.ownToolTipDismissDelay = ttm.getDismissDelay();
421
        this.ownToolTipReshowDelay = ttm.getReshowDelay();
422

    
423
        this.zoomAroundAnchor = false;
424
    }
425

    
426
    /**
427
     * Returns the chart contained in the panel.
428
     *
429
     * @return The chart (possibly <code>null</code>).
430
     */
431
    public JFreeChart getChart() {
432
        return this.chart;
433
    }
434

    
435
    /**
436
     * Sets the chart that is displayed in the panel.
437
     *
438
     * @param chart  the chart (<code>null</code> permitted).
439
     */
440
    public void setChart(JFreeChart chart) {
441

    
442
        // stop listening for changes to the existing chart
443
        if (this.chart != null) {
444
            this.chart.removeChangeListener(this);
445
            this.chart.removeProgressListener(this);
446
        }
447

    
448
        // add the new chart
449
        this.chart = chart;
450
        if (chart != null) {
451
            this.chart.addChangeListener(this);
452
            this.chart.addProgressListener(this);
453
            Plot plot = chart.getPlot();
454
            this.domainZoomable = false;
455
            this.rangeZoomable = false;
456
            if (plot instanceof Zoomable) {
457
                Zoomable z = (Zoomable) plot;
458
                this.domainZoomable = z.isDomainZoomable();
459
                this.rangeZoomable = z.isRangeZoomable();
460
                this.orientation = z.getOrientation();
461
            }
462
        }
463
        else {
464
            this.domainZoomable = false;
465
            this.rangeZoomable = false;
466
        }
467
        if (this.useBuffer) {
468
            this.refreshBuffer = true;
469
        }
470
        repaint();
471

    
472
    }
473

    
474
    /**
475
     * Returns the minimum drawing width for charts.
476
     * <P>
477
     * If the width available on the panel is less than this, then the chart is
478
     * drawn at the minimum width then scaled down to fit.
479
     *
480
     * @return The minimum drawing width.
481
     */
482
    public int getMinimumDrawWidth() {
483
        return this.minimumDrawWidth;
484
    }
485

    
486
    /**
487
     * Sets the minimum drawing width for the chart on this panel.
488
     * <P>
489
     * At the time the chart is drawn on the panel, if the available width is
490
     * less than this amount, the chart will be drawn using the minimum width
491
     * then scaled down to fit the available space.
492
     *
493
     * @param width  The width.
494
     */
495
    public void setMinimumDrawWidth(int width) {
496
        this.minimumDrawWidth = width;
497
    }
498

    
499
    /**
500
     * Returns the maximum drawing width for charts.
501
     * <P>
502
     * If the width available on the panel is greater than this, then the chart
503
     * is drawn at the maximum width then scaled up to fit.
504
     *
505
     * @return The maximum drawing width.
506
     */
507
    public int getMaximumDrawWidth() {
508
        return this.maximumDrawWidth;
509
    }
510

    
511
    /**
512
     * Sets the maximum drawing width for the chart on this panel.
513
     * <P>
514
     * At the time the chart is drawn on the panel, if the available width is
515
     * greater than this amount, the chart will be drawn using the maximum
516
     * width then scaled up to fit the available space.
517
     *
518
     * @param width  The width.
519
     */
520
    public void setMaximumDrawWidth(int width) {
521
        this.maximumDrawWidth = width;
522
    }
523

    
524
    /**
525
     * Returns the minimum drawing height for charts.
526
     * <P>
527
     * If the height available on the panel is less than this, then the chart
528
     * is drawn at the minimum height then scaled down to fit.
529
     *
530
     * @return The minimum drawing height.
531
     */
532
    public int getMinimumDrawHeight() {
533
        return this.minimumDrawHeight;
534
    }
535

    
536
    /**
537
     * Sets the minimum drawing height for the chart on this panel.
538
     * <P>
539
     * At the time the chart is drawn on the panel, if the available height is
540
     * less than this amount, the chart will be drawn using the minimum height
541
     * then scaled down to fit the available space.
542
     *
543
     * @param height  The height.
544
     */
545
    public void setMinimumDrawHeight(int height) {
546
        this.minimumDrawHeight = height;
547
    }
548

    
549
    /**
550
     * Returns the maximum drawing height for charts.
551
     * <P>
552
     * If the height available on the panel is greater than this, then the
553
     * chart is drawn at the maximum height then scaled up to fit.
554
     *
555
     * @return The maximum drawing height.
556
     */
557
    public int getMaximumDrawHeight() {
558
        return this.maximumDrawHeight;
559
    }
560

    
561
    /**
562
     * Sets the maximum drawing height for the chart on this panel.
563
     * <P>
564
     * At the time the chart is drawn on the panel, if the available height is
565
     * greater than this amount, the chart will be drawn using the maximum
566
     * height then scaled up to fit the available space.
567
     *
568
     * @param height  The height.
569
     */
570
    public void setMaximumDrawHeight(int height) {
571
        this.maximumDrawHeight = height;
572
    }
573

    
574
    /**
575
     * Returns the X scale factor for the chart.  This will be 1.0 if no 
576
     * scaling has been used.
577
     * 
578
     * @return The scale factor.
579
     */
580
    public double getScaleX() {
581
        return this.scaleX;
582
    }
583
    
584
    /**
585
     * Returns the Y scale factory for the chart.  This will be 1.0 if no 
586
     * scaling has been used.
587
     * 
588
     * @return The scale factor.
589
     */
590
    public double getScaleY() {
591
        return this.scaleY;
592
    }
593
    
594
    /**
595
     * Returns the anchor point.
596
     * 
597
     * @return The anchor point (possibly <code>null</code>).
598
     */
599
    public Point2D getAnchor() {
600
        return this.anchor;   
601
    }
602
    
603
    /**
604
     * Sets the anchor point.  This method is provided for the use of 
605
     * subclasses, not end users.
606
     * 
607
     * @param anchor  the anchor point (<code>null</code> permitted).
608
     */
609
    protected void setAnchor(Point2D anchor) {
610
        this.anchor = anchor;   
611
    }
612
    
613
    /**
614
     * Returns the popup menu.
615
     *
616
     * @return The popup menu.
617
     */
618
    public JPopupMenu getPopupMenu() {
619
        return this.popup;
620
    }
621

    
622
    /**
623
     * Sets the popup menu for the panel.
624
     *
625
     * @param popup  the popup menu (<code>null</code> permitted).
626
     */
627
    public void setPopupMenu(JPopupMenu popup) {
628
        this.popup = popup;
629
    }
630

    
631
    /**
632
     * Returns the chart rendering info from the most recent chart redraw.
633
     *
634
     * @return The chart rendering info.
635
     */
636
    public ChartRenderingInfo getChartRenderingInfo() {
637
        return this.info;
638
    }
639

    
640
    /**
641
     * A convenience method that switches on mouse-based zooming.
642
     *
643
     * @param flag  <code>true</code> enables zooming and rectangle fill on 
644
     *              zoom.
645
     */
646
    public void setMouseZoomable(boolean flag) {
647
        setMouseZoomable(flag, true);
648
    }
649

    
650
    /**
651
     * A convenience method that switches on mouse-based zooming.
652
     *
653
     * @param flag  <code>true</code> if zooming enabled
654
     * @param fillRectangle  <code>true</code> if zoom rectangle is filled,
655
     *                       false if rectangle is shown as outline only.
656
     */
657
    public void setMouseZoomable(boolean flag, boolean fillRectangle) {
658
        setDomainZoomable(flag);
659
        setRangeZoomable(flag);
660
        setFillZoomRectangle(fillRectangle);
661
    }
662

    
663
    /**
664
     * Returns the flag that determines whether or not zooming is enabled for 
665
     * the domain axis.
666
     * 
667
     * @return A boolean.
668
     */
669
    public boolean isDomainZoomable() {
670
        return this.domainZoomable;
671
    }
672
    
673
    /**
674
     * Sets the flag that controls whether or not zooming is enable for the 
675
     * domain axis.  A check is made to ensure that the current plot supports
676
     * zooming for the domain values.
677
     *
678
     * @param flag  <code>true</code> enables zooming if possible.
679
     */
680
    public void setDomainZoomable(boolean flag) {
681
        if (flag) {
682
            Plot plot = this.chart.getPlot();
683
            if (plot instanceof Zoomable) {
684
                Zoomable z = (Zoomable) plot;
685
                this.domainZoomable = flag && (z.isDomainZoomable());  
686
            }
687
        }
688
        else {
689
            this.domainZoomable = false;
690
        }
691
    }
692

    
693
    /**
694
     * Returns the flag that determines whether or not zooming is enabled for 
695
     * the range axis.
696
     * 
697
     * @return A boolean.
698
     */
699
    public boolean isRangeZoomable() {
700
        return this.rangeZoomable;
701
    }
702
    
703
    /**
704
     * A flag that controls mouse-based zooming on the vertical axis.
705
     *
706
     * @param flag  <code>true</code> enables zooming.
707
     */
708
    public void setRangeZoomable(boolean flag) {
709
        if (flag) {
710
            Plot plot = this.chart.getPlot();
711
            if (plot instanceof Zoomable) {
712
                Zoomable z = (Zoomable) plot;
713
                this.rangeZoomable = flag && (z.isRangeZoomable());  
714
            }
715
        }
716
        else {
717
            this.rangeZoomable = false;
718
        }
719
    }
720

    
721
    /**
722
     * Returns the flag that controls whether or not the zoom rectangle is
723
     * filled when drawn.
724
     * 
725
     * @return A boolean.
726
     */
727
    public boolean getFillZoomRectangle() {
728
        return this.fillZoomRectangle;
729
    }
730
    
731
    /**
732
     * A flag that controls how the zoom rectangle is drawn.
733
     *
734
     * @param flag  <code>true</code> instructs to fill the rectangle on
735
     *              zoom, otherwise it will be outlined.
736
     */
737
    public void setFillZoomRectangle(boolean flag) {
738
        this.fillZoomRectangle = flag;
739
    }
740

    
741
    /**
742
     * Returns the zoom trigger distance.  This controls how far the mouse must
743
     * move before a zoom action is triggered.
744
     * 
745
     * @return The distance (in Java2D units).
746
     */
747
    public int getZoomTriggerDistance() {
748
        return this.zoomTriggerDistance;
749
    }
750
    
751
    /**
752
     * Sets the zoom trigger distance.  This controls how far the mouse must 
753
     * move before a zoom action is triggered.
754
     * 
755
     * @param distance  the distance (in Java2D units).
756
     */
757
    public void setZoomTriggerDistance(int distance) {
758
        this.zoomTriggerDistance = distance;
759
    }
760
    
761
    /**
762
     * Returns the flag that controls whether or not a horizontal axis trace
763
     * line is drawn over the plot area at the current mouse location.
764
     * 
765
     * @return A boolean.
766
     */
767
    public boolean getHorizontalAxisTrace() {
768
        return this.horizontalAxisTrace;    
769
    }
770
    
771
    /**
772
     * A flag that controls trace lines on the horizontal axis.
773
     *
774
     * @param flag  <code>true</code> enables trace lines for the mouse
775
     *      pointer on the horizontal axis.
776
     */
777
    public void setHorizontalAxisTrace(boolean flag) {
778
        this.horizontalAxisTrace = flag;
779
    }
780
    
781
    /**
782
     * Returns the horizontal trace line.
783
     * 
784
     * @return The horizontal trace line (possibly <code>null</code>).
785
     */
786
    protected Line2D getHorizontalTraceLine() {
787
        return this.horizontalTraceLine;   
788
    }
789
    
790
    /**
791
     * Sets the horizontal trace line.
792
     * 
793
     * @param line  the line (<code>null</code> permitted).
794
     */
795
    protected void setHorizontalTraceLine(Line2D line) {
796
        this.horizontalTraceLine = line;   
797
    }
798

    
799
    /**
800
     * Returns the flag that controls whether or not a vertical axis trace
801
     * line is drawn over the plot area at the current mouse location.
802
     * 
803
     * @return A boolean.
804
     */
805
    public boolean getVerticalAxisTrace() {
806
        return this.verticalAxisTrace;    
807
    }
808
    
809
    /**
810
     * A flag that controls trace lines on the vertical axis.
811
     *
812
     * @param flag  <code>true</code> enables trace lines for the mouse
813
     *              pointer on the vertical axis.
814
     */
815
    public void setVerticalAxisTrace(boolean flag) {
816
        this.verticalAxisTrace = flag;
817
    }
818

    
819
    /**
820
     * Returns the vertical trace line.
821
     * 
822
     * @return The vertical trace line (possibly <code>null</code>).
823
     */
824
    protected Line2D getVerticalTraceLine() {
825
        return this.verticalTraceLine;   
826
    }
827
    
828
    /**
829
     * Sets the vertical trace line.
830
     * 
831
     * @param line  the line (<code>null</code> permitted).
832
     */
833
    protected void setVerticalTraceLine(Line2D line) {
834
        this.verticalTraceLine = line;   
835
    }
836
    
837
    /**
838
     * Returns the default directory for the "save as" option.
839
     * 
840
     * @return The default directory (possibly <code>null</code>).
841
     * 
842
     * @since 1.0.7
843
     */
844
    public File getDefaultDirectoryForSaveAs() {
845
        return this.defaultDirectoryForSaveAs;
846
    }
847

    
848
    /**
849
     * Sets the default directory for the "save as" option.  If you set this
850
     * to <code>null</code>, the user's default directory will be used.
851
     * 
852
     * @param directory  the directory (<code>null</code> permitted).
853
     * 
854
     * @since 1.0.7
855
     */
856
    public void setDefaultDirectoryForSaveAs(File directory) {
857
        if (directory != null) {
858
            if (!directory.isDirectory()) {
859
                throw new IllegalArgumentException(
860
                        "The 'directory' argument is not a directory.");
861
            }
862
        }
863
        this.defaultDirectoryForSaveAs = directory;
864
    }
865
    
866
    /**
867
     * Returns <code>true</code> if file extensions should be enforced, and 
868
     * <code>false</code> otherwise.
869
     *
870
     * @return The flag.
871
     * 
872
     * @see #setEnforceFileExtensions(boolean)
873
     */
874
    public boolean isEnforceFileExtensions() {
875
        return this.enforceFileExtensions;
876
    }
877

    
878
    /**
879
     * Sets a flag that controls whether or not file extensions are enforced.
880
     *
881
     * @param enforce  the new flag value.
882
     * 
883
     * @see #isEnforceFileExtensions()
884
     */
885
    public void setEnforceFileExtensions(boolean enforce) {
886
        this.enforceFileExtensions = enforce;
887
    }
888
    
889
    /**
890
     * Returns the flag that controls whether or not zoom operations are 
891
     * centered around the current anchor point.
892
     * 
893
     * @return A boolean.
894
     * 
895
     * @since 1.0.7
896
     * 
897
     * @see #setZoomAroundAnchor(boolean)
898
     */
899
    public boolean getZoomAroundAnchor() {
900
        return this.zoomAroundAnchor;
901
    }
902
    
903
    /**
904
     * Sets the flag that controls whether or not zoom operations are
905
     * centered around the current anchor point.
906
     * 
907
     * @param zoomAroundAnchor  the new flag value.
908
     * 
909
     * @since 1.0.7
910
     * 
911
     * @see #getZoomAroundAnchor()
912
     */
913
    public void setZoomAroundAnchor(boolean zoomAroundAnchor) {
914
        this.zoomAroundAnchor = zoomAroundAnchor;
915
    }
916

    
917
    /**
918
     * Switches the display of tooltips for the panel on or off.  Note that 
919
     * tooltips can only be displayed if the chart has been configured to
920
     * generate tooltip items.
921
     *
922
     * @param flag  <code>true</code> to enable tooltips, <code>false</code> to
923
     *              disable tooltips.
924
     */
925
    public void setDisplayToolTips(boolean flag) {
926
        if (flag) {
927
            ToolTipManager.sharedInstance().registerComponent(this);
928
        }
929
        else {
930
            ToolTipManager.sharedInstance().unregisterComponent(this);
931
        }
932
    }
933

    
934
    /**
935
     * Returns a string for the tooltip.
936
     *
937
     * @param e  the mouse event.
938
     *
939
     * @return A tool tip or <code>null</code> if no tooltip is available.
940
     */
941
    public String getToolTipText(MouseEvent e) {
942

    
943
        String result = null;
944
        if (this.info != null) {
945
            EntityCollection entities = this.info.getEntityCollection();
946
            if (entities != null) {
947
                Insets insets = getInsets();
948
                ChartEntity entity = entities.getEntity(
949
                        (int) ((e.getX() - insets.left) / this.scaleX),
950
                        (int) ((e.getY() - insets.top) / this.scaleY));
951
                if (entity != null) {
952
                    result = entity.getToolTipText();
953
                }
954
            }
955
        }
956
        return result;
957

    
958
    }
959

    
960
    /**
961
     * Translates a Java2D point on the chart to a screen location.
962
     *
963
     * @param java2DPoint  the Java2D point.
964
     *
965
     * @return The screen location.
966
     */
967
    public Point translateJava2DToScreen(Point2D java2DPoint) {
968
        Insets insets = getInsets();
969
        int x = (int) (java2DPoint.getX() * this.scaleX + insets.left);
970
        int y = (int) (java2DPoint.getY() * this.scaleY + insets.top);
971
        return new Point(x, y);
972
    }
973

    
974
    /**
975
     * Translates a panel (component) location to a Java2D point.
976
     *
977
     * @param screenPoint  the screen location (<code>null</code> not 
978
     *                     permitted).
979
     *
980
     * @return The Java2D coordinates.
981
     */
982
    public Point2D translateScreenToJava2D(Point screenPoint) {
983
        Insets insets = getInsets();
984
        double x = (screenPoint.getX() - insets.left) / this.scaleX;
985
        double y = (screenPoint.getY() - insets.top) / this.scaleY;
986
        return new Point2D.Double(x, y);
987
    }
988

    
989
    /**
990
     * Applies any scaling that is in effect for the chart drawing to the
991
     * given rectangle.
992
     *  
993
     * @param rect  the rectangle.
994
     * 
995
     * @return A new scaled rectangle.
996
     */
997
    public Rectangle2D scale(Rectangle2D rect) {
998
        Insets insets = getInsets();
999
        double x = rect.getX() * getScaleX() + insets.left;
1000
        double y = rect.getY() * this.getScaleY() + insets.top;
1001
        double w = rect.getWidth() * this.getScaleX();
1002
        double h = rect.getHeight() * this.getScaleY();
1003
        return new Rectangle2D.Double(x, y, w, h);
1004
    }
1005

    
1006
    /**
1007
     * Returns the chart entity at a given point.
1008
     * <P>
1009
     * This method will return null if there is (a) no entity at the given 
1010
     * point, or (b) no entity collection has been generated.
1011
     *
1012
     * @param viewX  the x-coordinate.
1013
     * @param viewY  the y-coordinate.
1014
     *
1015
     * @return The chart entity (possibly <code>null</code>).
1016
     */
1017
    public ChartEntity getEntityForPoint(int viewX, int viewY) {
1018

    
1019
        ChartEntity result = null;
1020
        if (this.info != null) {
1021
            Insets insets = getInsets();
1022
            double x = (viewX - insets.left) / this.scaleX;
1023
            double y = (viewY - insets.top) / this.scaleY;
1024
            EntityCollection entities = this.info.getEntityCollection();
1025
            result = entities != null ? entities.getEntity(x, y) : null; 
1026
        }
1027
        return result;
1028

    
1029
    }
1030

    
1031
    /**
1032
     * Returns the flag that controls whether or not the offscreen buffer
1033
     * needs to be refreshed.
1034
     * 
1035
     * @return A boolean.
1036
     */
1037
    public boolean getRefreshBuffer() {
1038
        return this.refreshBuffer;
1039
    }
1040
    
1041
    /**
1042
     * Sets the refresh buffer flag.  This flag is used to avoid unnecessary
1043
     * redrawing of the chart when the offscreen image buffer is used.
1044
     *
1045
     * @param flag  <code>true</code> indicates that the buffer should be 
1046
     *              refreshed.
1047
     */
1048
    public void setRefreshBuffer(boolean flag) {
1049
        this.refreshBuffer = flag;
1050
    }
1051

    
1052
    /**
1053
     * Paints the component by drawing the chart to fill the entire component,
1054
     * but allowing for the insets (which will be non-zero if a border has been
1055
     * set for this component).  To increase performance (at the expense of
1056
     * memory), an off-screen buffer image can be used.
1057
     *
1058
     * @param g  the graphics device for drawing on.
1059
     */
1060
    public void paintComponent(Graphics g) {
1061
        super.paintComponent(g);
1062
        if (this.chart == null) {
1063
            return;
1064
        }
1065
        Graphics2D g2 = (Graphics2D) g.create();
1066

    
1067
        // first determine the size of the chart rendering area...
1068
        Dimension size = getSize();
1069
        Insets insets = getInsets();
1070
        Rectangle2D available = new Rectangle2D.Double(insets.left, insets.top,
1071
                size.getWidth() - insets.left - insets.right,
1072
                size.getHeight() - insets.top - insets.bottom);
1073

    
1074
        // work out if scaling is required...
1075
        boolean scale = false;
1076
        double drawWidth = available.getWidth();
1077
        double drawHeight = available.getHeight();
1078
        this.scaleX = 1.0;
1079
        this.scaleY = 1.0;
1080

    
1081
        if (drawWidth < this.minimumDrawWidth) {
1082
            this.scaleX = drawWidth / this.minimumDrawWidth;
1083
            drawWidth = this.minimumDrawWidth;
1084
            scale = true;
1085
        }
1086
        else if (drawWidth > this.maximumDrawWidth) {
1087
            this.scaleX = drawWidth / this.maximumDrawWidth;
1088
            drawWidth = this.maximumDrawWidth;
1089
            scale = true;
1090
        }
1091

    
1092
        if (drawHeight < this.minimumDrawHeight) {
1093
            this.scaleY = drawHeight / this.minimumDrawHeight;
1094
            drawHeight = this.minimumDrawHeight;
1095
            scale = true;
1096
        }
1097
        else if (drawHeight > this.maximumDrawHeight) {
1098
            this.scaleY = drawHeight / this.maximumDrawHeight;
1099
            drawHeight = this.maximumDrawHeight;
1100
            scale = true;
1101
        }
1102

    
1103
        Rectangle2D chartArea = new Rectangle2D.Double(0.0, 0.0, drawWidth, 
1104
                drawHeight);
1105

    
1106
        // are we using the chart buffer?
1107
        if (this.useBuffer) {
1108

    
1109
            // if buffer is being refreshed, it needs clearing unless it is
1110
            // new - use the following flag to track this...
1111
            boolean clearBuffer = true;
1112
            
1113
            // do we need to resize the buffer?
1114
            if ((this.chartBuffer == null) 
1115
                    || (this.chartBufferWidth != available.getWidth())
1116
                    || (this.chartBufferHeight != available.getHeight())) {
1117
                this.chartBufferWidth = (int) available.getWidth();
1118
                this.chartBufferHeight = (int) available.getHeight();
1119
                this.chartBuffer = createImage(this.chartBufferWidth, 
1120
                        this.chartBufferHeight);
1121
//                GraphicsConfiguration gc = g2.getDeviceConfiguration();
1122
//                this.chartBuffer = gc.createCompatibleImage(
1123
//                        this.chartBufferWidth, this.chartBufferHeight, 
1124
//                        Transparency.TRANSLUCENT);
1125
                this.refreshBuffer = true;
1126
                clearBuffer = false;  // buffer is new, no clearing required
1127
            }
1128

    
1129
            // do we need to redraw the buffer?
1130
            if (this.refreshBuffer) {
1131

    
1132
                this.refreshBuffer = false; // clear the flag
1133

    
1134
                Rectangle2D bufferArea = new Rectangle2D.Double(
1135
                        0, 0, this.chartBufferWidth, this.chartBufferHeight);
1136

    
1137
                Graphics2D bufferG2 = (Graphics2D) 
1138
                        this.chartBuffer.getGraphics();
1139
                if (clearBuffer) {
1140
                    bufferG2.clearRect(0, 0, this.chartBufferWidth, 
1141
                            this.chartBufferHeight);
1142
                }
1143
                if (scale) {
1144
                    AffineTransform saved = bufferG2.getTransform();
1145
                    AffineTransform st = AffineTransform.getScaleInstance(
1146
                            this.scaleX, this.scaleY);
1147
                    bufferG2.transform(st);
1148
                    this.chart.draw(bufferG2, chartArea, this.anchor, 
1149
                            this.info);
1150
                    bufferG2.setTransform(saved);
1151
                }
1152
                else {
1153
                    this.chart.draw(bufferG2, bufferArea, this.anchor, 
1154
                            this.info);
1155
                }
1156

    
1157
            }
1158

    
1159
            // zap the buffer onto the panel...
1160
            g2.drawImage(this.chartBuffer, insets.left, insets.top, this);
1161
            g2.draw((Shape)activeROI.shapeList.get(1));
1162
          // Dibujar las rois que se encuentren activas
1163
        
1164
        }
1165

    
1166
        // or redrawing the chart every time...
1167
        else {
1168

    
1169
            AffineTransform saved = g2.getTransform();
1170
            g2.translate(insets.left, insets.top);
1171
            if (scale) {
1172
                AffineTransform st = AffineTransform.getScaleInstance(
1173
                        this.scaleX, this.scaleY);
1174
                g2.transform(st);
1175
            }
1176
            this.chart.draw(g2, chartArea, this.anchor, this.info);
1177
            g2.drawImage(this.chartBuffer, insets.left, insets.top, this);
1178
         
1179
            // Se pintan las Roi activa
1180
            drawsROIs(g2);
1181
            g2.setTransform(saved);
1182

    
1183
        }
1184
        
1185
        // Redraw the zoom rectangle (if present)
1186
      //  drawZoomRectangle(g2);
1187
        
1188
        g2.dispose();
1189

    
1190
        this.anchor = null;
1191
        this.verticalTraceLine = null;
1192
        this.horizontalTraceLine = null;
1193

    
1194
    }
1195

    
1196
  
1197
        /**
1198
     * Receives notification of changes to the chart, and redraws the chart.
1199
     *
1200
     * @param event  details of the chart change event.
1201
     */
1202
    public void chartChanged(ChartChangeEvent event) {
1203
        this.refreshBuffer = true;
1204
        Plot plot = this.chart.getPlot();
1205
        if (plot instanceof Zoomable) {
1206
            Zoomable z = (Zoomable) plot;
1207
            this.orientation = z.getOrientation();
1208
        }
1209
        repaint();
1210
    }
1211

    
1212
    /**
1213
     * Receives notification of a chart progress event.
1214
     *
1215
     * @param event  the event.
1216
     */
1217
    public void chartProgress(ChartProgressEvent event) {
1218
        // does nothing - override if necessary
1219
    }
1220

    
1221
    /**
1222
     * Handles action events generated by the popup menu.
1223
     *
1224
     * @param event  the event.
1225
     */
1226
    public void actionPerformed(ActionEvent event) {
1227

    
1228
        String command = event.getActionCommand();
1229

    
1230
        // many of the zoom methods need a screen location - all we have is 
1231
        // the zoomPoint, but it might be null.  Here we grab the x and y
1232
        // coordinates, or use defaults...
1233
        double screenX = -1.0;
1234
        double screenY = -1.0;
1235
        if (this.zoomPoint != null) {
1236
            screenX = this.zoomPoint.getX();
1237
            screenY = this.zoomPoint.getY();
1238
        }
1239
        
1240
        if (command.equals(SAVE_COMMAND)) {
1241
            try {
1242
                doSaveAs();
1243
            }
1244
            catch (IOException e) {
1245
                e.printStackTrace();
1246
            }
1247
        }
1248
        else if (command.equals(PRINT_COMMAND)) {
1249
            createChartPrintJob();
1250
        }
1251
        else if (command.equals(ZOOM_IN_BOTH_COMMAND)) {
1252
            zoomInBoth(screenX, screenY);
1253
        }
1254
        else if (command.equals(ZOOM_IN_DOMAIN_COMMAND)) {
1255
            zoomInDomain(screenX, screenY);
1256
        }
1257
        else if (command.equals(ZOOM_IN_RANGE_COMMAND)) {
1258
            zoomInRange(screenX, screenY);
1259
        }
1260
        else if (command.equals(ZOOM_OUT_BOTH_COMMAND)) {
1261
            zoomOutBoth(screenX, screenY);
1262
        }
1263
        else if (command.equals(ZOOM_OUT_DOMAIN_COMMAND)) {
1264
            zoomOutDomain(screenX, screenY);
1265
        }
1266
        else if (command.equals(ZOOM_OUT_RANGE_COMMAND)) {
1267
            zoomOutRange(screenX, screenY);
1268
        }
1269
        else if (command.equals(ZOOM_RESET_BOTH_COMMAND)) {
1270
            restoreAutoBounds();
1271
        }
1272
        else if (command.equals(ZOOM_RESET_DOMAIN_COMMAND)) {
1273
            restoreAutoDomainBounds();
1274
        }
1275
        else if (command.equals(ZOOM_RESET_RANGE_COMMAND)) {
1276
            restoreAutoRangeBounds();
1277
        }
1278
        else if (command.equals(NEW_CLASS_COMMAND)) {
1279
            // Definicion de nueba clase
1280
                activeROI= new ROIChart(roiList.getNexColor(),roiList.getdefaultName());
1281
                updateList();
1282
        }
1283

    
1284
        // Acciones para el borrado de la visualizacion de las rois
1285
        else if (command.equals(CLEAR_CHART)) {
1286
            // Definicion de nueba clase        
1287
                
1288
        }
1289

    
1290
    }
1291
    
1292
    
1293
    public void  updateList(){
1294
            // Actualizo la roi activa en la lista
1295
            roiList.getListRois().remove(activeROI.getName());
1296
            roiList.add(activeROI);
1297
            
1298
    }
1299
    
1300
    
1301

    
1302
    /**
1303
     * Handles a 'mouse entered' event. This method changes the tooltip delays
1304
     * of ToolTipManager.sharedInstance() to the possibly different values set 
1305
     * for this chart panel. 
1306
     *
1307
     * @param e  the mouse event.
1308
     */
1309
    public void mouseEntered(MouseEvent e) {
1310
        if (!this.ownToolTipDelaysActive) {
1311
            ToolTipManager ttm = ToolTipManager.sharedInstance();
1312
            
1313
            this.originalToolTipInitialDelay = ttm.getInitialDelay();
1314
            ttm.setInitialDelay(this.ownToolTipInitialDelay);
1315
    
1316
            this.originalToolTipReshowDelay = ttm.getReshowDelay();
1317
            ttm.setReshowDelay(this.ownToolTipReshowDelay);
1318
            
1319
            this.originalToolTipDismissDelay = ttm.getDismissDelay();
1320
            ttm.setDismissDelay(this.ownToolTipDismissDelay);
1321
    
1322
            this.ownToolTipDelaysActive = true;
1323
        }
1324
    }
1325

    
1326
    /**
1327
     * Handles a 'mouse exited' event. This method resets the tooltip delays of
1328
     * ToolTipManager.sharedInstance() to their
1329
     * original values in effect before mouseEntered()
1330
     *
1331
     * @param e  the mouse event.
1332
     */
1333
    public void mouseExited(MouseEvent e) {
1334
        if (this.ownToolTipDelaysActive) {
1335
            // restore original tooltip dealys 
1336
            ToolTipManager ttm = ToolTipManager.sharedInstance();       
1337
            ttm.setInitialDelay(this.originalToolTipInitialDelay);
1338
            ttm.setReshowDelay(this.originalToolTipReshowDelay);
1339
            ttm.setDismissDelay(this.originalToolTipDismissDelay);
1340
            this.ownToolTipDelaysActive = false;
1341
        }
1342
    }
1343

    
1344
    /**
1345
     * Handles a 'mouse pressed' event.
1346
     * <P>
1347
     * This event is the popup trigger on Unix/Linux.  For Windows, the popup
1348
     * trigger is the 'mouse released' event.
1349
     *
1350
     * @param e  The mouse event.
1351
     */
1352
    public void mousePressed(MouseEvent e) {
1353
        if (this.zoomRectangle == null) {
1354
            Rectangle2D screenDataArea = getScreenDataArea(e.getX(), e.getY());
1355
            if (screenDataArea != null) {
1356
                this.zoomPoint = getPointInRectangle(e.getX(), e.getY(), 
1357
                        screenDataArea);
1358
            }
1359
            else {
1360
                this.zoomPoint = null;
1361
            }
1362
            if (e.isPopupTrigger()) {
1363
                if (this.popup != null) {
1364
                    displayPopupMenu(e.getX(), e.getY());
1365
                }
1366
            }
1367
        }
1368
    }
1369
    
1370
    /**
1371
     * Returns a point based on (x, y) but constrained to be within the bounds
1372
     * of the given rectangle.  This method could be moved to JCommon.
1373
     * 
1374
     * @param x  the x-coordinate.
1375
     * @param y  the y-coordinate.
1376
     * @param area  the rectangle (<code>null</code> not permitted).
1377
     * 
1378
     * @return A point within the rectangle.
1379
     */
1380
    private Point getPointInRectangle(int x, int y, Rectangle2D area) {
1381
        x = (int) Math.max(Math.ceil(area.getMinX()), Math.min(x, 
1382
                Math.floor(area.getMaxX())));   
1383
        y = (int) Math.max(Math.ceil(area.getMinY()), Math.min(y, 
1384
                Math.floor(area.getMaxY())));
1385
        return new Point(x, y);
1386
    }
1387

    
1388
    /**
1389
     * Handles a 'mouse dragged' event.
1390
     *
1391
     * @param e  the mouse event.
1392
     */
1393
    public void mouseDragged(MouseEvent e) {
1394

    
1395
        // if the popup menu has already been triggered, then ignore dragging...
1396
        if (this.popup != null && this.popup.isShowing()) {
1397
            return;
1398
        }
1399
        // if no initial zoom point was set, ignore dragging...
1400
        if (this.zoomPoint == null) {
1401
            return;
1402
        }
1403
        Graphics2D g2 = (Graphics2D) getGraphics();
1404

    
1405
        // Erase the previous zoom rectangle (if any)...
1406
        drawZoomRectangle(g2);
1407

    
1408
        boolean hZoom = false;
1409
        boolean vZoom = false;
1410
        if (this.orientation == PlotOrientation.HORIZONTAL) {
1411
            hZoom = this.rangeZoomable;
1412
            vZoom = this.domainZoomable;
1413
        }
1414
        else {
1415
            hZoom = this.domainZoomable;              
1416
            vZoom = this.rangeZoomable;
1417
        }
1418
        Rectangle2D scaledDataArea = getScreenDataArea(
1419
                (int) this.zoomPoint.getX(), (int) this.zoomPoint.getY());
1420
        if (hZoom && vZoom) {
1421
            // selected rectangle shouldn't extend outside the data area...
1422
            double xmax = Math.min(e.getX(), scaledDataArea.getMaxX());
1423
            double ymax = Math.min(e.getY(), scaledDataArea.getMaxY());
1424
            this.zoomRectangle = new Rectangle2D.Double(
1425
                    this.zoomPoint.getX(), this.zoomPoint.getY(),
1426
                    xmax - this.zoomPoint.getX(), ymax - this.zoomPoint.getY());
1427
        }
1428
        else if (hZoom) {
1429
            double xmax = Math.min(e.getX(), scaledDataArea.getMaxX());
1430
            this.zoomRectangle = new Rectangle2D.Double(
1431
                    this.zoomPoint.getX(), scaledDataArea.getMinY(),
1432
                    xmax - this.zoomPoint.getX(), scaledDataArea.getHeight());
1433
        }
1434
        else if (vZoom) {
1435
            double ymax = Math.min(e.getY(), scaledDataArea.getMaxY());
1436
            this.zoomRectangle = new Rectangle2D.Double(
1437
                    scaledDataArea.getMinX(), this.zoomPoint.getY(),
1438
                    scaledDataArea.getWidth(), ymax - this.zoomPoint.getY());
1439
        }
1440

    
1441
        // Draw the new zoom rectangle...
1442
        drawZoomRectangle(g2);
1443
        
1444
        g2.dispose();
1445

    
1446
    }
1447

    
1448
    /**
1449
     * Handles a 'mouse released' event.  On Windows, we need to check if this 
1450
     * is a popup trigger, but only if we haven't already been tracking a zoom
1451
     * rectangle.
1452
     *
1453
     * @param e  information about the event.
1454
     */
1455
    public void mouseReleased(MouseEvent e) {
1456

    
1457
        if (this.zoomRectangle != null) {
1458
            boolean hZoom = false;
1459
            boolean vZoom = false;
1460
            if (this.orientation == PlotOrientation.HORIZONTAL) {
1461
                hZoom = this.rangeZoomable;
1462
                vZoom = this.domainZoomable;
1463
            }
1464
            else {
1465
                hZoom = this.domainZoomable;              
1466
                vZoom = this.rangeZoomable;
1467
            }
1468
            
1469
            boolean zoomTrigger1 = hZoom && Math.abs(e.getX() 
1470
                - this.zoomPoint.getX()) >= this.zoomTriggerDistance;
1471
            boolean zoomTrigger2 = vZoom && Math.abs(e.getY() 
1472
                - this.zoomPoint.getY()) >= this.zoomTriggerDistance;
1473
            if (zoomTrigger1 || zoomTrigger2) {
1474
                if ((hZoom && (e.getX() < this.zoomPoint.getX())) 
1475
                    || (vZoom && (e.getY() < this.zoomPoint.getY()))) {
1476
                    restoreAutoBounds();
1477
                }
1478
                else {
1479
                    double x, y, w, h;
1480
                    Rectangle2D screenDataArea = getScreenDataArea(
1481
                            (int) this.zoomPoint.getX(), 
1482
                            (int) this.zoomPoint.getY());
1483
                    // for mouseReleased event, (horizontalZoom || verticalZoom)
1484
                    // will be true, so we can just test for either being false;
1485
                    // otherwise both are true
1486
                    if (!vZoom) {
1487
                        x = this.zoomPoint.getX();
1488
                        y = screenDataArea.getMinY();
1489
                        w = Math.min(this.zoomRectangle.getWidth(),
1490
                                screenDataArea.getMaxX() 
1491
                                - this.zoomPoint.getX());
1492
                        h = screenDataArea.getHeight();
1493
                    }
1494
                    else if (!hZoom) {
1495
                        x = screenDataArea.getMinX();
1496
                        y = this.zoomPoint.getY();
1497
                        w = screenDataArea.getWidth();
1498
                        h = Math.min(this.zoomRectangle.getHeight(),
1499
                                screenDataArea.getMaxY() 
1500
                                - this.zoomPoint.getY());
1501
                    }
1502
                    else {
1503
                        x = this.zoomPoint.getX();
1504
                        y = this.zoomPoint.getY();
1505
                        w = Math.min(this.zoomRectangle.getWidth(),
1506
                                screenDataArea.getMaxX() 
1507
                                - this.zoomPoint.getX());
1508
                        h = Math.min(this.zoomRectangle.getHeight(),
1509
                                screenDataArea.getMaxY() 
1510
                                - this.zoomPoint.getY());
1511
                    }
1512
                    if (activeROI!= null)
1513
                    {
1514
                            Rectangle2D rectangleArea = new Rectangle2D.Double(x, y, w, h);
1515
                            g2 = (Graphics2D)getGraphics();
1516
                            g2.setPaint(activeROI.getColor());
1517
           
1518
                            g2.draw(rectangleArea);
1519
                            activeROI.add(rectangleArea, getRange(rectangleArea));
1520
           
1521
                            Range r[]=getRange(rectangleArea);
1522
                            System.out.print("\n"+r[0]);
1523
                            System.out.print("\n");
1524
                            System.out.print(r[1]);
1525
                    }
1526
                  
1527
                }
1528
                this.zoomPoint = null;
1529
                this.zoomRectangle = null;
1530
                updateUI();
1531
            }
1532
            else {
1533
                // Erase the zoom rectangle
1534
                Graphics2D g2 = (Graphics2D) getGraphics();
1535
                drawZoomRectangle(g2);
1536
                g2.dispose();
1537
                this.zoomPoint = null;
1538
                this.zoomRectangle = null;
1539
            }
1540

    
1541
        }
1542

    
1543
        else if (e.isPopupTrigger()) {
1544
            if (this.popup != null) {
1545
                displayPopupMenu(e.getX(), e.getY());
1546
            }
1547
        }
1548

    
1549
    }
1550
    
1551
    
1552
   
1553
    /**
1554
     * Receives notification of mouse clicks on the panel. These are
1555
     * translated and passed on to any registered chart mouse click listeners.
1556
     *
1557
     * @param event  Information about the mouse event.
1558
     */
1559
    public void mouseClicked(MouseEvent event) {
1560

    
1561
        Insets insets = getInsets();
1562
        int x = (int) ((event.getX() - insets.left) / this.scaleX);
1563
        int y = (int) ((event.getY() - insets.top) / this.scaleY);
1564

    
1565
        this.anchor = new Point2D.Double(x, y);
1566
        if (this.chart == null) {
1567
            return;
1568
        }
1569
        this.chart.setNotify(true);  // force a redraw 
1570
        // new entity code...
1571
        Object[] listeners = this.chartMouseListeners.getListeners(
1572
                ChartMouseListener.class);
1573
        if (listeners.length == 0) {
1574
            return;
1575
        }
1576

    
1577
        ChartEntity entity = null;
1578
        if (this.info != null) {
1579
            EntityCollection entities = this.info.getEntityCollection();
1580
            if (entities != null) {
1581
                entity = entities.getEntity(x, y);
1582
            }
1583
        }
1584
        ChartMouseEvent chartEvent = new ChartMouseEvent(getChart(), event, 
1585
                entity);
1586
        for (int i = listeners.length - 1; i >= 0; i -= 1) {
1587
            ((ChartMouseListener) listeners[i]).chartMouseClicked(chartEvent);
1588
        }
1589
        updateUI();
1590

    
1591
    }
1592

    
1593
    /**
1594
     * Implementation of the MouseMotionListener's method.
1595
     *
1596
     * @param e  the event.
1597
     */
1598
    public void mouseMoved(MouseEvent e) {
1599
      
1600
    /*        g2 = (Graphics2D) getGraphics();
1601
        if (this.horizontalAxisTrace) {
1602
            drawHorizontalAxisTrace(g2, e.getX());
1603
        }
1604
        if (this.verticalAxisTrace) {
1605
            drawVerticalAxisTrace(g2, e.getY());
1606
        }
1607
        g2.dispose();
1608
        
1609
        Object[] listeners = this.chartMouseListeners.getListeners(
1610
                ChartMouseListener.class);
1611
        if (listeners.length == 0) {
1612
            return;
1613
        }
1614
        Insets insets = getInsets();
1615
        int x = (int) ((e.getX() - insets.left) / this.scaleX);
1616
        int y = (int) ((e.getY() - insets.top) / this.scaleY);
1617

1618
        ChartEntity entity = null;
1619
        if (this.info != null) {
1620
            EntityCollection entities = this.info.getEntityCollection();
1621
            if (entities != null) {
1622
                entity = entities.getEntity(x, y);
1623
            }
1624
        }
1625
        
1626
        // we can only generate events if the panel's chart is not null
1627
        // (see bug report 1556951)
1628
        if (this.chart != null) {
1629
            ChartMouseEvent event = new ChartMouseEvent(getChart(), e, entity);
1630
            for (int i = listeners.length - 1; i >= 0; i -= 1) {
1631
                ((ChartMouseListener) listeners[i]).chartMouseMoved(event);
1632
            }
1633
        }*/
1634

    
1635
    }
1636

    
1637
    /**
1638
     * Zooms in on an anchor point (specified in screen coordinate space).
1639
     *
1640
     * @param x  the x value (in screen coordinates).
1641
     * @param y  the y value (in screen coordinates).
1642
     */
1643
    public void zoomInBoth(double x, double y) {
1644
        zoomInDomain(x, y);
1645
        zoomInRange(x, y);
1646
    }
1647

    
1648
    /**
1649
     * Decreases the length of the domain axis, centered about the given
1650
     * coordinate on the screen.  The length of the domain axis is reduced
1651
     * by the value of {@link #getZoomInFactor()}.
1652
     *
1653
     * @param x  the x coordinate (in screen coordinates).
1654
     * @param y  the y-coordinate (in screen coordinates).
1655
     */
1656
    public void zoomInDomain(double x, double y) {
1657
       
1658
    }
1659

    
1660
    /**
1661
     * Decreases the length of the range axis, centered about the given
1662
     * coordinate on the screen.  The length of the range axis is reduced by
1663
     * the value of {@link #getZoomInFactor()}.
1664
     *
1665
     * @param x  the x-coordinate (in screen coordinates).
1666
     * @param y  the y coordinate (in screen coordinates).
1667
     */
1668
    public void zoomInRange(double x, double y) {
1669
       
1670
    }
1671

    
1672
    /**
1673
     * Zooms out on an anchor point (specified in screen coordinate space).
1674
     *
1675
     * @param x  the x value (in screen coordinates).
1676
     * @param y  the y value (in screen coordinates).
1677
     */
1678
    public void zoomOutBoth(double x, double y) {
1679
        zoomOutDomain(x, y);
1680
        zoomOutRange(x, y);
1681
    }
1682

    
1683
    /**
1684
     * Increases the length of the domain axis, centered about the given
1685
     * coordinate on the screen.  The length of the domain axis is increased
1686
     * by the value of {@link #getZoomOutFactor()}.
1687
     *
1688
     * @param x  the x coordinate (in screen coordinates).
1689
     * @param y  the y-coordinate (in screen coordinates).
1690
     */
1691
    public void zoomOutDomain(double x, double y) {
1692
      
1693
    }
1694

    
1695
    /**
1696
     * Increases the length the range axis, centered about the given
1697
     * coordinate on the screen.  The length of the range axis is increased
1698
     * by the value of {@link #getZoomOutFactor()}.
1699
     *
1700
     * @param x  the x coordinate (in screen coordinates).
1701
     * @param y  the y-coordinate (in screen coordinates).
1702
     */
1703
    public void zoomOutRange(double x, double y) {
1704
       
1705
    }
1706

    
1707
    /**
1708
     * Zooms in on a selected region.
1709
     *
1710
     * @param selection  the selected region.
1711
     */
1712
    public Range[] getRange(Rectangle2D selection) {
1713

    
1714
            Range[] rangos= new Range[2];
1715
            
1716
        // get the origin of the zoom selection in the Java2D space used for
1717
        // drawing the chart (that is, before any scaling to fit the panel)
1718
        Point2D selectOrigin = translateScreenToJava2D(new Point(
1719
                (int) Math.ceil(selection.getX()), 
1720
                (int) Math.ceil(selection.getY())));
1721
        PlotRenderingInfo plotInfo = this.info.getPlotInfo();
1722
        Rectangle2D scaledDataArea = getScreenDataArea(
1723
                (int) selection.getCenterX(), (int) selection.getCenterY());
1724
        if ((selection.getHeight() > 0) && (selection.getWidth() > 0)) {
1725

    
1726
            double hLower = (selection.getMinX() - scaledDataArea.getMinX()) 
1727
                / scaledDataArea.getWidth();
1728
            double hUpper = (selection.getMaxX() - scaledDataArea.getMinX()) 
1729
                / scaledDataArea.getWidth();
1730
            double vLower = (scaledDataArea.getMaxY() - selection.getMaxY()) 
1731
                / scaledDataArea.getHeight();
1732
            double vUpper = (scaledDataArea.getMaxY() - selection.getMinY()) 
1733
                / scaledDataArea.getHeight();
1734

    
1735
            Plot p = this.chart.getPlot();
1736
            if (p instanceof ScatterPlotChart) {
1737
              ScatterPlotChart z = (ScatterPlotChart) p;
1738
                if (z.getOrientation() == PlotOrientation.HORIZONTAL) {
1739
                   rangos[0]= z.getRangeX(vLower, vUpper, plotInfo, selectOrigin);
1740
                    rangos[1]=z.getRangeY(hLower, hUpper, plotInfo, selectOrigin);
1741
                }
1742
                else {
1743
                        // devolver las coordenadas del rectangulo.
1744
                        rangos[0]=z.getRangeX(hLower, hUpper, plotInfo, selectOrigin);
1745
                        rangos[1]=z.getRangeY(vLower, vUpper, plotInfo, selectOrigin);
1746
                }
1747
            }
1748

    
1749
        }
1750

    
1751
        return rangos;
1752
    }
1753

    
1754
    /**
1755
     * Restores the auto-range calculation on both axes.
1756
     */
1757
    public void restoreAutoBounds() {
1758
        restoreAutoDomainBounds();
1759
        restoreAutoRangeBounds();
1760
    }
1761

    
1762
    /**
1763
     * Restores the auto-range calculation on the domain axis.
1764
     */
1765
    public void restoreAutoDomainBounds() {
1766
        Plot p = this.chart.getPlot();
1767
        if (p instanceof Zoomable) {
1768
            Zoomable z = (Zoomable) p;
1769
            // we need to guard against this.zoomPoint being null
1770
            Point zp = (this.zoomPoint != null ? this.zoomPoint : new Point());
1771
            z.zoomDomainAxes(0.0, this.info.getPlotInfo(), zp);
1772
        }
1773
    }
1774

    
1775
    /**
1776
     * Restores the auto-range calculation on the range axis.
1777
     */
1778
    public void restoreAutoRangeBounds() {
1779
        Plot p = this.chart.getPlot();
1780
        if (p instanceof Zoomable) {
1781
            Zoomable z = (Zoomable) p;
1782
            // we need to guard against this.zoomPoint being null
1783
            Point zp = (this.zoomPoint != null ? this.zoomPoint : new Point());
1784
            z.zoomRangeAxes(0.0, this.info.getPlotInfo(), zp);
1785
        }
1786
    }
1787

    
1788
    /**
1789
     * Returns the data area for the chart (the area inside the axes) with the
1790
     * current scaling applied (that is, the area as it appears on screen).
1791
     *
1792
     * @return The scaled data area.
1793
     */
1794
    public Rectangle2D getScreenDataArea() {
1795
        Rectangle2D dataArea = this.info.getPlotInfo().getDataArea();
1796
        Insets insets = getInsets();
1797
        double x = dataArea.getX() * this.scaleX + insets.left;
1798
        double y = dataArea.getY() * this.scaleY + insets.top;
1799
        double w = dataArea.getWidth() * this.scaleX;
1800
        double h = dataArea.getHeight() * this.scaleY;
1801
        return new Rectangle2D.Double(x, y, w, h);
1802
    }
1803
    
1804
    /**
1805
     * Returns the data area (the area inside the axes) for the plot or subplot,
1806
     * with the current scaling applied.
1807
     *
1808
     * @param x  the x-coordinate (for subplot selection).
1809
     * @param y  the y-coordinate (for subplot selection).
1810
     * 
1811
     * @return The scaled data area.
1812
     */
1813
    public Rectangle2D getScreenDataArea(int x, int y) {
1814
        PlotRenderingInfo plotInfo = this.info.getPlotInfo();
1815
        Rectangle2D result;
1816
        if (plotInfo.getSubplotCount() == 0) {
1817
            result = getScreenDataArea();
1818
        } 
1819
        else {
1820
            // get the origin of the zoom selection in the Java2D space used for
1821
            // drawing the chart (that is, before any scaling to fit the panel)
1822
            Point2D selectOrigin = translateScreenToJava2D(new Point(x, y));
1823
            int subplotIndex = plotInfo.getSubplotIndex(selectOrigin);
1824
            if (subplotIndex == -1) {
1825
                return null;
1826
            }
1827
            result = scale(plotInfo.getSubplotInfo(subplotIndex).getDataArea());
1828
        }
1829
        return result;
1830
    }
1831
    
1832
    /**
1833
     * Returns the initial tooltip delay value used inside this chart panel.
1834
     *
1835
     * @return An integer representing the initial delay value, in milliseconds.
1836
     * 
1837
     * @see javax.swing.ToolTipManager#getInitialDelay()
1838
     */
1839
    public int getInitialDelay() {
1840
        return this.ownToolTipInitialDelay;
1841
    }
1842
    
1843
    /**
1844
     * Returns the reshow tooltip delay value used inside this chart panel.
1845
     *
1846
     * @return An integer representing the reshow  delay value, in milliseconds.
1847
     * 
1848
     * @see javax.swing.ToolTipManager#getReshowDelay()
1849
     */
1850
    public int getReshowDelay() {
1851
        return this.ownToolTipReshowDelay;  
1852
    }
1853

    
1854
    /**
1855
     * Returns the dismissal tooltip delay value used inside this chart panel.
1856
     *
1857
     * @return An integer representing the dismissal delay value, in 
1858
     *         milliseconds.
1859
     * 
1860
     * @see javax.swing.ToolTipManager#getDismissDelay()
1861
     */
1862
    public int getDismissDelay() {
1863
        return this.ownToolTipDismissDelay; 
1864
    }
1865
    
1866
    /**
1867
     * Specifies the initial delay value for this chart panel.
1868
     *
1869
     * @param delay  the number of milliseconds to delay (after the cursor has 
1870
     *               paused) before displaying. 
1871
     * 
1872
     * @see javax.swing.ToolTipManager#setInitialDelay(int)
1873
     */
1874
    public void setInitialDelay(int delay) {
1875
        this.ownToolTipInitialDelay = delay;
1876
    }
1877
    
1878
    /**
1879
     * Specifies the amount of time before the user has to wait initialDelay 
1880
     * milliseconds before a tooltip will be shown.
1881
     *
1882
     * @param delay  time in milliseconds
1883
     * 
1884
     * @see javax.swing.ToolTipManager#setReshowDelay(int)
1885
     */
1886
    public void setReshowDelay(int delay) {
1887
        this.ownToolTipReshowDelay = delay;  
1888
    }
1889

    
1890
    /**
1891
     * Specifies the dismissal delay value for this chart panel.
1892
     *
1893
     * @param delay the number of milliseconds to delay before taking away the 
1894
     *              tooltip
1895
     * 
1896
     * @see javax.swing.ToolTipManager#setDismissDelay(int)
1897
     */
1898
    public void setDismissDelay(int delay) {
1899
        this.ownToolTipDismissDelay = delay; 
1900
    }
1901
    
1902
    /**
1903
     * Returns the zoom in factor.
1904
     * 
1905
     * @return The zoom in factor.
1906
     * 
1907
     * @see #setZoomInFactor(double)
1908
     */
1909
    public double getZoomInFactor() {
1910
        return this.zoomInFactor;   
1911
    }
1912
    
1913
    /**
1914
     * Sets the zoom in factor.
1915
     * 
1916
     * @param factor  the factor.
1917
     * 
1918
     * @see #getZoomInFactor()
1919
     */
1920
    public void setZoomInFactor(double factor) {
1921
        this.zoomInFactor = factor;
1922
    }
1923
    
1924
    /**
1925
     * Returns the zoom out factor.
1926
     * 
1927
     * @return The zoom out factor.
1928
     * 
1929
     * @see #setZoomOutFactor(double)
1930
     */
1931
    public double getZoomOutFactor() {
1932
        return this.zoomOutFactor;   
1933
    }
1934
    
1935
    /**
1936
     * Sets the zoom out factor.
1937
     * 
1938
     * @param factor  the factor.
1939
     * 
1940
     * @see #getZoomOutFactor()
1941
     */
1942
    public void setZoomOutFactor(double factor) {
1943
        this.zoomOutFactor = factor;
1944
    }
1945
    
1946
    /**
1947
     * Draws zoom rectangle (if present).
1948
     * The drawing is performed in XOR mode, therefore
1949
     * when this method is called twice in a row,
1950
     * the second call will completely restore the state
1951
     * of the canvas.
1952
     * 
1953
     * @param g2 the graphics device. 
1954
     */
1955
    private void drawZoomRectangle(Graphics2D g2) {
1956
        // Set XOR mode to draw the zoom rectangle
1957
        g2.setXORMode(Color.gray);
1958
        if (this.zoomRectangle != null) {
1959
            if (this.fillZoomRectangle) {
1960
                g2.fill(this.zoomRectangle);
1961
            }
1962
            else {
1963
                g2.draw(this.zoomRectangle);
1964
            }
1965
        }
1966
        // Reset to the default 'overwrite' mode
1967
        g2.setPaintMode();
1968
    }
1969
    
1970
    /**
1971
     * Draws a vertical line used to trace the mouse position to the horizontal 
1972
     * axis.
1973
     *
1974
     * @param g2 the graphics device.
1975
     * @param x  the x-coordinate of the trace line.
1976
     */
1977
    private void drawHorizontalAxisTrace(Graphics2D g2, int x) {
1978

    
1979
        Rectangle2D dataArea = getScreenDataArea();
1980

    
1981
        g2.setXORMode(Color.orange);
1982
        if (((int) dataArea.getMinX() < x) && (x < (int) dataArea.getMaxX())) {
1983

    
1984
            if (this.verticalTraceLine != null) {
1985
                g2.draw(this.verticalTraceLine);
1986
                this.verticalTraceLine.setLine(x, (int) dataArea.getMinY(), x, 
1987
                        (int) dataArea.getMaxY());
1988
            }
1989
            else {
1990
                this.verticalTraceLine = new Line2D.Float(x, 
1991
                        (int) dataArea.getMinY(), x, (int) dataArea.getMaxY());
1992
            }
1993
            g2.draw(this.verticalTraceLine);
1994
        }
1995

    
1996
        // Reset to the default 'overwrite' mode
1997
        g2.setPaintMode();
1998
    }
1999

    
2000
    /**
2001
     * Draws a horizontal line used to trace the mouse position to the vertical
2002
     * axis.
2003
     *
2004
     * @param g2 the graphics device.
2005
     * @param y  the y-coordinate of the trace line.
2006
     */
2007
    private void drawVerticalAxisTrace(Graphics2D g2, int y) {
2008

    
2009
        Rectangle2D dataArea = getScreenDataArea();
2010

    
2011
        g2.setXORMode(Color.orange);
2012
        if (((int) dataArea.getMinY() < y) && (y < (int) dataArea.getMaxY())) {
2013

    
2014
            if (this.horizontalTraceLine != null) {
2015
                g2.draw(this.horizontalTraceLine);
2016
                this.horizontalTraceLine.setLine((int) dataArea.getMinX(), y, 
2017
                        (int) dataArea.getMaxX(), y);
2018
            }
2019
            else {
2020
                this.horizontalTraceLine = new Line2D.Float(
2021
                        (int) dataArea.getMinX(), y, (int) dataArea.getMaxX(), 
2022
                        y);
2023
            }
2024
            g2.draw(this.horizontalTraceLine);
2025
        }
2026

    
2027
        // Reset to the default 'overwrite' mode
2028
        g2.setPaintMode();
2029
    }
2030

    
2031
    /**
2032
     * Displays a dialog that allows the user to edit the properties for the
2033
     * current chart.
2034
     * 
2035
     * @since 1.0.3
2036
     */
2037
    public void doEditChartProperties() {
2038

    
2039
      
2040
               
2041
               
2042
               /*ChartEditorManager.getChartEditor(this.chart);
2043
        int result = JOptionPane.showConfirmDialog(this, editor, 
2044
                localizationResources.getString("Chart_Properties"),
2045
                JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
2046
        if (result == JOptionPane.OK_OPTION) {
2047
            editor.updateChart(this.chart);
2048
        }
2049
*/
2050
    }
2051

    
2052
    /**
2053
     * Opens a file chooser and gives the user an opportunity to save the chart
2054
     * in PNG format.
2055
     *
2056
     * @throws IOException if there is an I/O error.
2057
     */
2058
    public void doSaveAs() throws IOException {
2059

    
2060
        JFileChooser fileChooser = new JFileChooser();
2061
        fileChooser.setCurrentDirectory(this.defaultDirectoryForSaveAs);
2062
        ExtensionFileFilter filter = new ExtensionFileFilter(
2063
                localizationResources.getString("PNG_Image_Files"), ".png");
2064
        fileChooser.addChoosableFileFilter(filter);
2065

    
2066
        int option = fileChooser.showSaveDialog(this);
2067
        if (option == JFileChooser.APPROVE_OPTION) {
2068
            String filename = fileChooser.getSelectedFile().getPath();
2069
            if (isEnforceFileExtensions()) {
2070
                if (!filename.endsWith(".png")) {
2071
                    filename = filename + ".png";
2072
                }
2073
            }
2074
            ChartUtilities.saveChartAsPNG(new File(filename), this.chart, 
2075
                    getWidth(), getHeight());
2076
        }
2077

    
2078
    }
2079

    
2080
    /**
2081
     * Creates a print job for the chart.
2082
     */
2083
    public void createChartPrintJob() {
2084

    
2085
        PrinterJob job = PrinterJob.getPrinterJob();
2086
        PageFormat pf = job.defaultPage();
2087
        PageFormat pf2 = job.pageDialog(pf);
2088
        if (pf2 != pf) {
2089
            job.setPrintable(this, pf2);
2090
            if (job.printDialog()) {
2091
                try {
2092
                    job.print();
2093
                }
2094
                catch (PrinterException e) {
2095
                    JOptionPane.showMessageDialog(this, e);
2096
                }
2097
            }
2098
        }
2099

    
2100
    }
2101

    
2102
    /**
2103
     * Prints the chart on a single page.
2104
     *
2105
     * @param g  the graphics context.
2106
     * @param pf  the page format to use.
2107
     * @param pageIndex  the index of the page. If not <code>0</code>, nothing 
2108
     *                   gets print.
2109
     *
2110
     * @return The result of printing.
2111
     */
2112
    public int print(Graphics g, PageFormat pf, int pageIndex) {
2113

    
2114
        if (pageIndex != 0) {
2115
            return NO_SUCH_PAGE;
2116
        }
2117
        Graphics2D g2 = (Graphics2D) g;
2118
        double x = pf.getImageableX();
2119
        double y = pf.getImageableY();
2120
        double w = pf.getImageableWidth();
2121
        double h = pf.getImageableHeight();
2122
        this.chart.draw(g2, new Rectangle2D.Double(x, y, w, h), this.anchor, 
2123
                null);
2124
        return PAGE_EXISTS;
2125

    
2126
    }
2127

    
2128
    /**
2129
     * Adds a listener to the list of objects listening for chart mouse events.
2130
     *
2131
     * @param listener  the listener (<code>null</code> not permitted).
2132
     */
2133
    public void addChartMouseListener(ChartMouseListener listener) {
2134
        if (listener == null) {
2135
            throw new IllegalArgumentException("Null 'listener' argument.");
2136
        }
2137
        this.chartMouseListeners.add(ChartMouseListener.class, listener);
2138
    }
2139

    
2140
    /**
2141
     * Removes a listener from the list of objects listening for chart mouse 
2142
     * events.
2143
     *
2144
     * @param listener  the listener.
2145
     */
2146
    public void removeChartMouseListener(ChartMouseListener listener) {
2147
        this.chartMouseListeners.remove(ChartMouseListener.class, listener);
2148
    }
2149

    
2150
    /**
2151
     * Returns an array of the listeners of the given type registered with the
2152
     * panel.
2153
     * 
2154
     * @param listenerType  the listener type.
2155
     * 
2156
     * @return An array of listeners.
2157
     */
2158
    public EventListener[] getListeners(Class listenerType) {
2159
        if (listenerType == ChartMouseListener.class) {
2160
            // fetch listeners from local storage
2161
            return this.chartMouseListeners.getListeners(listenerType);
2162
        }
2163
        else {
2164
            return super.getListeners(listenerType);
2165
        }
2166
    }
2167

    
2168
    /**
2169
     * Creates a popup menu for the panel.
2170
     *
2171
     * @param properties  include a menu item for the chart property editor.
2172
     * @param save  include a menu item for saving the chart.
2173
     * @param print  include a menu item for printing the chart.
2174
     * @param zoom  include menu items for zooming.
2175
     *
2176
     * @return The popup menu.
2177
     */
2178
    protected JPopupMenu createPopupMenu(boolean properties, 
2179
                                         boolean save, 
2180
                                         boolean print,
2181
                                         boolean zoom) {
2182

    
2183
        JPopupMenu result = new JPopupMenu("Chart:");
2184
        boolean separator = false;
2185

    
2186
        JMenuItem newClassItem = new JMenuItem( PluginServices.getText(this,"new_class"));
2187
        newClassItem.setActionCommand(NEW_CLASS_COMMAND);
2188
        newClassItem.addActionListener(this);
2189
        result.add(newClassItem);
2190
        separator = true;
2191
        
2192

    
2193
        JMenuItem newClassItem2 = new JMenuItem( PluginServices.getText(this,"clear_chart"));
2194
        newClassItem2.setActionCommand(CLEAR_CHART);
2195
        newClassItem2.addActionListener(this);
2196
        result.add(newClassItem2);
2197
        separator = true;
2198
        
2199
        
2200
        if (properties) {
2201
         
2202
        }
2203

    
2204
        if (save) {
2205
            if (separator) {
2206
                result.addSeparator();
2207
                separator = false;
2208
            }
2209
            JMenuItem saveItem = new JMenuItem(
2210
                    localizationResources.getString("Save_as..."));
2211
            saveItem.setActionCommand(SAVE_COMMAND);
2212
            saveItem.addActionListener(this);
2213
            result.add(saveItem);
2214
            separator = true;
2215
        }
2216

    
2217
        if (print) {
2218
            if (separator) {
2219
                result.addSeparator();
2220
                separator = false;
2221
            }
2222
            JMenuItem printItem = new JMenuItem(
2223
                    localizationResources.getString("Print..."));
2224
            printItem.setActionCommand(PRINT_COMMAND);
2225
            printItem.addActionListener(this);
2226
            result.add(printItem);
2227
            separator = true;
2228
        }
2229

    
2230
        if (zoom) {
2231
            if (separator) {
2232
                result.addSeparator();
2233
                separator = false;
2234
            }
2235

    
2236
            
2237
            
2238
            
2239
            
2240
            JMenu zoomInMenu = new JMenu(
2241
                    localizationResources.getString("Zoom_In"));
2242

    
2243
            this.zoomInBothMenuItem = new JMenuItem(
2244
                    localizationResources.getString("All_Axes"));
2245
            this.zoomInBothMenuItem.setActionCommand(ZOOM_IN_BOTH_COMMAND);
2246
            this.zoomInBothMenuItem.addActionListener(this);
2247
            zoomInMenu.add(this.zoomInBothMenuItem);
2248

    
2249
            zoomInMenu.addSeparator();
2250

    
2251
            this.zoomInDomainMenuItem = new JMenuItem(
2252
                    localizationResources.getString("Domain_Axis"));
2253
            this.zoomInDomainMenuItem.setActionCommand(ZOOM_IN_DOMAIN_COMMAND);
2254
            this.zoomInDomainMenuItem.addActionListener(this);
2255
            zoomInMenu.add(this.zoomInDomainMenuItem);
2256

    
2257
            this.zoomInRangeMenuItem = new JMenuItem(
2258
                    localizationResources.getString("Range_Axis"));
2259
            this.zoomInRangeMenuItem.setActionCommand(ZOOM_IN_RANGE_COMMAND);
2260
            this.zoomInRangeMenuItem.addActionListener(this);
2261
            zoomInMenu.add(this.zoomInRangeMenuItem);
2262

    
2263
            result.add(zoomInMenu);
2264

    
2265
            JMenu zoomOutMenu = new JMenu(
2266
                    localizationResources.getString("Zoom_Out"));
2267

    
2268
            this.zoomOutBothMenuItem = new JMenuItem(
2269
                    localizationResources.getString("All_Axes"));
2270
            this.zoomOutBothMenuItem.setActionCommand(ZOOM_OUT_BOTH_COMMAND);
2271
            this.zoomOutBothMenuItem.addActionListener(this);
2272
            zoomOutMenu.add(this.zoomOutBothMenuItem);
2273

    
2274
            zoomOutMenu.addSeparator();
2275

    
2276
            this.zoomOutDomainMenuItem = new JMenuItem(
2277
                    localizationResources.getString("Domain_Axis"));
2278
            this.zoomOutDomainMenuItem.setActionCommand(
2279
                    ZOOM_OUT_DOMAIN_COMMAND);
2280
            this.zoomOutDomainMenuItem.addActionListener(this);
2281
            zoomOutMenu.add(this.zoomOutDomainMenuItem);
2282

    
2283
            this.zoomOutRangeMenuItem = new JMenuItem(
2284
                    localizationResources.getString("Range_Axis"));
2285
            this.zoomOutRangeMenuItem.setActionCommand(ZOOM_OUT_RANGE_COMMAND);
2286
            this.zoomOutRangeMenuItem.addActionListener(this);
2287
            zoomOutMenu.add(this.zoomOutRangeMenuItem);
2288

    
2289
            result.add(zoomOutMenu);
2290

    
2291
            JMenu autoRangeMenu = new JMenu(
2292
                    localizationResources.getString("Auto_Range"));
2293

    
2294
            this.zoomResetBothMenuItem = new JMenuItem(
2295
                    localizationResources.getString("All_Axes"));
2296
            this.zoomResetBothMenuItem.setActionCommand(
2297
                    ZOOM_RESET_BOTH_COMMAND);
2298
            this.zoomResetBothMenuItem.addActionListener(this);
2299
            autoRangeMenu.add(this.zoomResetBothMenuItem);
2300

    
2301
            autoRangeMenu.addSeparator();
2302
            this.zoomResetDomainMenuItem = new JMenuItem(
2303
                    localizationResources.getString("Domain_Axis"));
2304
            this.zoomResetDomainMenuItem.setActionCommand(
2305
                    ZOOM_RESET_DOMAIN_COMMAND);
2306
            this.zoomResetDomainMenuItem.addActionListener(this);
2307
            autoRangeMenu.add(this.zoomResetDomainMenuItem);
2308

    
2309
            this.zoomResetRangeMenuItem = new JMenuItem(
2310
                    localizationResources.getString("Range_Axis"));
2311
            this.zoomResetRangeMenuItem.setActionCommand(
2312
                    ZOOM_RESET_RANGE_COMMAND);
2313
            this.zoomResetRangeMenuItem.addActionListener(this);
2314
            autoRangeMenu.add(this.zoomResetRangeMenuItem);
2315

    
2316
            result.addSeparator();
2317
            result.add(autoRangeMenu);
2318

    
2319
        }
2320

    
2321
        return result;
2322

    
2323
    }
2324

    
2325
    /**
2326
     * The idea is to modify the zooming options depending on the type of chart 
2327
     * being displayed by the panel.
2328
     *
2329
     * @param x  horizontal position of the popup.
2330
     * @param y  vertical position of the popup.
2331
     */
2332
    protected void displayPopupMenu(int x, int y) {
2333

    
2334
            
2335
        if (this.popup != null) {
2336

    
2337
            // go through each zoom menu item and decide whether or not to 
2338
            // enable it...
2339
            Plot plot = this.chart.getPlot();
2340
            boolean isDomainZoomable = false;
2341
            boolean isRangeZoomable = false;
2342
            if (plot instanceof Zoomable) {
2343
                Zoomable z = (Zoomable) plot;
2344
                isDomainZoomable = z.isDomainZoomable();
2345
                isRangeZoomable = z.isRangeZoomable();
2346
            }
2347
            
2348
            if (this.zoomInDomainMenuItem != null) {
2349
                this.zoomInDomainMenuItem.setEnabled(isDomainZoomable);
2350
            }
2351
            if (this.zoomOutDomainMenuItem != null) {
2352
                this.zoomOutDomainMenuItem.setEnabled(isDomainZoomable);
2353
            } 
2354
            if (this.zoomResetDomainMenuItem != null) {
2355
                this.zoomResetDomainMenuItem.setEnabled(isDomainZoomable);
2356
            }
2357

    
2358
            if (this.zoomInRangeMenuItem != null) {
2359
                this.zoomInRangeMenuItem.setEnabled(isRangeZoomable);
2360
            }
2361
            if (this.zoomOutRangeMenuItem != null) {
2362
                this.zoomOutRangeMenuItem.setEnabled(isRangeZoomable);
2363
            }
2364

    
2365
            if (this.zoomResetRangeMenuItem != null) {
2366
                this.zoomResetRangeMenuItem.setEnabled(isRangeZoomable);
2367
            }
2368

    
2369
            if (this.zoomInBothMenuItem != null) {
2370
                this.zoomInBothMenuItem.setEnabled(isDomainZoomable 
2371
                        && isRangeZoomable);
2372
            }
2373
            if (this.zoomOutBothMenuItem != null) {
2374
                this.zoomOutBothMenuItem.setEnabled(isDomainZoomable 
2375
                        && isRangeZoomable);
2376
            }
2377
            if (this.zoomResetBothMenuItem != null) {
2378
                this.zoomResetBothMenuItem.setEnabled(isDomainZoomable 
2379
                        && isRangeZoomable);
2380
            }
2381

    
2382
           // updateUI();
2383
            this.popup.show(this, x, y);
2384
           
2385
          
2386
        }
2387

    
2388
    }
2389
    
2390
    
2391
    /* (non-Javadoc)
2392
     * @see javax.swing.JPanel#updateUI()
2393
     */
2394
    public void updateUI() {
2395
        // here we need to update the UI for the popup menu, if the panel
2396
        // has one...
2397
        if (this.popup != null) {
2398
            SwingUtilities.updateComponentTreeUI(this.popup);
2399
        }
2400
        super.updateUI();
2401
      
2402
          
2403
    }
2404
    
2405
    
2406
    // Devuelve la lista de ROIs definidas sobre el grafico.
2407
    public ROIChartList getROIChartList(){
2408
            return roiList;
2409
    }
2410
    
2411
    
2412
    // Borra una ROI del grafico (con todas las geometrias asociadas)
2413
    public void clearROIChart(int index){
2414
            roiList.deleteROI(index);
2415
    }
2416
    
2417
    
2418
    /**Pinta la lista de ROis Visibles sobre el grafico*/
2419
    public void drawsROIs(Graphics2D g2){
2420
            
2421
            Iterator iterator= roiList.getList().iterator();
2422
            ROIChart roiDraw=null;
2423
            
2424
            while(iterator.hasNext()){
2425
                    
2426
                    roiDraw= (ROIChart)iterator.next();
2427
                    if(activeROI.equals(roiDraw)){
2428
                            g2.setPaint(roiDraw.getColor());
2429
                            for(int i=0; i<roiDraw.shapeList.size(); i++){
2430
                                    g2.fill((Shape)roiDraw.shapeList.get(i));
2431
                            }
2432
                    
2433
                    }
2434
                            
2435
                    else if(roiDraw.shapeList.size()>0){                
2436
                            g2.setPaint(roiDraw.getColor());
2437
                            for(int i=0; i<roiDraw.shapeList.size(); i++){
2438
                                    g2.setPaint(roiDraw.getColor());
2439
                                    g2.draw((Shape)roiDraw.shapeList.get(i));
2440
                                    }        
2441
                    }
2442
                    
2443
            }
2444
    }
2445

    
2446
            
2447
   
2448
    
2449
    public void cleanChart(){
2450
            
2451
            
2452
    }
2453
    
2454

    
2455
}
2456