1 package net.sf.openrocket.gui.scalefigure;
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.text.DecimalFormat;
6 import java.util.Arrays;
7 import java.util.EventObject;
9 import javax.swing.JButton;
10 import javax.swing.JComboBox;
11 import javax.swing.JPanel;
13 import net.miginfocom.swing.MigLayout;
14 import net.sf.openrocket.gui.util.Icons;
15 import net.sf.openrocket.util.StateChangeListener;
17 public class ScaleSelector extends JPanel {
19 // Ready zoom settings
20 private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.#%");
22 private static final double[] ZOOM_LEVELS = { 0.15, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0 };
23 private static final String ZOOM_FIT = "Fit";
24 private static final String[] ZOOM_SETTINGS;
26 ZOOM_SETTINGS = new String[ZOOM_LEVELS.length+1];
27 for (int i=0; i<ZOOM_LEVELS.length; i++)
28 ZOOM_SETTINGS[i] = PERCENT_FORMAT.format(ZOOM_LEVELS[i]);
29 ZOOM_SETTINGS[ZOOM_SETTINGS.length-1] = ZOOM_FIT;
33 private final ScaleScrollPane scrollPane;
34 private JComboBox zoomSelector;
37 public ScaleSelector(ScaleScrollPane scroll) {
38 super(new MigLayout());
40 this.scrollPane = scroll;
43 JButton button = new JButton(Icons.ZOOM_OUT);
44 button.addActionListener(new ActionListener() {
45 public void actionPerformed(ActionEvent e) {
46 double scale = scrollPane.getScaling();
47 scale = getPreviousScale(scale);
48 scrollPane.setScaling(scale);
53 // Zoom level selector
54 String[] settings = ZOOM_SETTINGS;
55 if (!scrollPane.isFittingAllowed()) {
56 settings = Arrays.copyOf(settings, settings.length-1);
59 zoomSelector = new JComboBox(settings);
60 zoomSelector.setEditable(true);
62 zoomSelector.addActionListener(new ActionListener() {
63 public void actionPerformed(ActionEvent e) {
65 String text = (String)zoomSelector.getSelectedItem();
66 text = text.replaceAll("%", "").trim();
68 if (text.toLowerCase().startsWith(ZOOM_FIT.toLowerCase()) &&
69 scrollPane.isFittingAllowed()) {
70 scrollPane.setFitting(true);
75 double n = Double.parseDouble(text);
80 scrollPane.setScaling(n);
82 } catch (NumberFormatException ignore) {
88 scrollPane.getFigure().addChangeListener(new StateChangeListener() {
90 public void stateChanged(EventObject e) {
94 add(zoomSelector,"gap rel");
98 button = new JButton(Icons.ZOOM_IN);
99 button.addActionListener(new ActionListener() {
100 public void actionPerformed(ActionEvent e) {
101 double scale = scrollPane.getScaling();
102 scale = getNextScale(scale);
103 scrollPane.setScaling(scale);
106 add(button,"gapleft rel");
112 private void setZoomText() {
114 double zoom = scrollPane.getScaling();
115 text = PERCENT_FORMAT.format(zoom);
116 if (scrollPane.isFitting()) {
117 text = "Fit ("+text+")";
119 if (!text.equals(zoomSelector.getSelectedItem()))
120 zoomSelector.setSelectedItem(text);
125 private double getPreviousScale(double scale) {
127 for (i=0; i<ZOOM_LEVELS.length-1; i++) {
128 if (scale > ZOOM_LEVELS[i]+0.05 && scale < ZOOM_LEVELS[i+1]+0.05)
129 return ZOOM_LEVELS[i];
131 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length/2]) {
132 // scale is large, drop to next lowest full 100%
133 scale = Math.ceil(scale-1.05);
134 return Math.max(scale, ZOOM_LEVELS[i]);
141 private double getNextScale(double scale) {
143 for (i=0; i<ZOOM_LEVELS.length-1; i++) {
144 if (scale > ZOOM_LEVELS[i]-0.05 && scale < ZOOM_LEVELS[i+1]-0.05)
145 return ZOOM_LEVELS[i+1];
147 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length/2]) {
148 // scale is large, give next full 100%
149 scale = Math.floor(scale+1.05);