major optimization updates
[debian/openrocket] / src / net / sf / openrocket / gui / scalefigure / AbstractScaleFigure.java
1 package net.sf.openrocket.gui.scalefigure;
2
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.util.LinkedList;
6 import java.util.List;
7
8 import javax.swing.JPanel;
9 import javax.swing.event.ChangeEvent;
10 import javax.swing.event.ChangeListener;
11
12 import net.sf.openrocket.util.Prefs;
13
14
15 public abstract class AbstractScaleFigure extends JPanel implements ScaleFigure {
16         
17         // Number of pixels to leave at edges when fitting figure
18         private static final int DEFAULT_BORDER_PIXELS_WIDTH = 30;
19         private static final int DEFAULT_BORDER_PIXELS_HEIGHT = 20;
20         
21
22         protected final double dpi;
23         
24         protected double scale = 1.0;
25         protected double scaling = 1.0;
26         
27         protected int borderPixelsWidth = DEFAULT_BORDER_PIXELS_WIDTH;
28         protected int borderPixelsHeight = DEFAULT_BORDER_PIXELS_HEIGHT;
29         
30         protected final List<ChangeListener> listeners = new LinkedList<ChangeListener>();
31         
32         
33         public AbstractScaleFigure() {
34                 this.dpi = Prefs.getDPI();
35                 this.scaling = 1.0;
36                 this.scale = dpi / 0.0254 * scaling;
37                 
38                 setBackground(Color.WHITE);
39                 setOpaque(true);
40         }
41         
42         
43
44         public abstract void updateFigure();
45         
46         public abstract double getFigureWidth();
47         
48         public abstract double getFigureHeight();
49         
50         
51         @Override
52         public double getScaling() {
53                 return scaling;
54         }
55         
56         @Override
57         public double getAbsoluteScale() {
58                 return scale;
59         }
60         
61         @Override
62         public void setScaling(double scaling) {
63                 if (Double.isInfinite(scaling) || Double.isNaN(scaling))
64                         scaling = 1.0;
65                 if (scaling < 0.001)
66                         scaling = 0.001;
67                 if (scaling > 1000)
68                         scaling = 1000;
69                 if (Math.abs(this.scaling - scaling) < 0.01)
70                         return;
71                 this.scaling = scaling;
72                 this.scale = dpi / 0.0254 * scaling;
73                 updateFigure();
74         }
75         
76         @Override
77         public void setScaling(Dimension bounds) {
78                 double zh = 1, zv = 1;
79                 int w = bounds.width - 2 * borderPixelsWidth - 20;
80                 int h = bounds.height - 2 * borderPixelsHeight - 20;
81                 
82                 if (w < 10)
83                         w = 10;
84                 if (h < 10)
85                         h = 10;
86                 
87                 zh = (w) / getFigureWidth();
88                 zv = (h) / getFigureHeight();
89                 
90                 double s = Math.min(zh, zv) / dpi * 0.0254 - 0.001;
91                 
92                 setScaling(s);
93         }
94         
95         
96         @Override
97         public Dimension getBorderPixels() {
98                 return new Dimension(borderPixelsWidth, borderPixelsHeight);
99         }
100         
101         @Override
102         public void setBorderPixels(int width, int height) {
103                 this.borderPixelsWidth = width;
104                 this.borderPixelsHeight = height;
105         }
106         
107         
108         @Override
109         public void addChangeListener(ChangeListener listener) {
110                 listeners.add(0, listener);
111         }
112         
113         @Override
114         public void removeChangeListener(ChangeListener listener) {
115                 listeners.remove(listener);
116         }
117         
118         private ChangeEvent changeEvent = null;
119         
120         protected void fireChangeEvent() {
121                 ChangeListener[] list = listeners.toArray(new ChangeListener[0]);
122                 for (ChangeListener l : list) {
123                         if (changeEvent == null)
124                                 changeEvent = new ChangeEvent(this);
125                         l.stateChanged(changeEvent);
126                 }
127         }
128         
129 }