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