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;
8 import java.util.Locale;
10 import javax.swing.JButton;
11 import javax.swing.JComboBox;
12 import javax.swing.JPanel;
14 import net.miginfocom.swing.MigLayout;
15 import net.sf.openrocket.gui.util.Icons;
16 import net.sf.openrocket.util.StateChangeListener;
18 public class ScaleSelector extends JPanel {
20 // Ready zoom settings
21 private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.#%");
23 private static final double[] ZOOM_LEVELS = { 0.15, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0 };
24 private static final String ZOOM_FIT = "Fit";
25 private static final String[] ZOOM_SETTINGS;
27 ZOOM_SETTINGS = new String[ZOOM_LEVELS.length + 1];
28 for (int i = 0; i < ZOOM_LEVELS.length; i++)
29 ZOOM_SETTINGS[i] = PERCENT_FORMAT.format(ZOOM_LEVELS[i]);
30 ZOOM_SETTINGS[ZOOM_SETTINGS.length - 1] = ZOOM_FIT;
34 private final ScaleScrollPane scrollPane;
35 private JComboBox zoomSelector;
38 public ScaleSelector(ScaleScrollPane scroll) {
39 super(new MigLayout());
41 this.scrollPane = scroll;
44 JButton button = new JButton(Icons.ZOOM_OUT);
45 button.addActionListener(new ActionListener() {
47 public void actionPerformed(ActionEvent e) {
48 double scale = scrollPane.getScaling();
49 scale = getPreviousScale(scale);
50 scrollPane.setScaling(scale);
55 // Zoom level selector
56 String[] settings = ZOOM_SETTINGS;
57 if (!scrollPane.isFittingAllowed()) {
58 settings = Arrays.copyOf(settings, settings.length - 1);
61 zoomSelector = new JComboBox(settings);
62 zoomSelector.setEditable(true);
64 zoomSelector.addActionListener(new ActionListener() {
66 public void actionPerformed(ActionEvent e) {
68 String text = (String) zoomSelector.getSelectedItem();
69 text = text.replaceAll("%", "").trim();
71 if (text.toLowerCase(Locale.getDefault()).startsWith(ZOOM_FIT.toLowerCase(Locale.getDefault())) &&
72 scrollPane.isFittingAllowed()) {
73 scrollPane.setFitting(true);
78 double n = Double.parseDouble(text);
83 scrollPane.setScaling(n);
85 } catch (NumberFormatException ignore) {
91 scrollPane.getFigure().addChangeListener(new StateChangeListener() {
93 public void stateChanged(EventObject e) {
97 add(zoomSelector, "gap rel");
101 button = new JButton(Icons.ZOOM_IN);
102 button.addActionListener(new ActionListener() {
104 public void actionPerformed(ActionEvent e) {
105 double scale = scrollPane.getScaling();
106 scale = getNextScale(scale);
107 scrollPane.setScaling(scale);
110 add(button, "gapleft rel");
116 private void setZoomText() {
118 double zoom = scrollPane.getScaling();
119 text = PERCENT_FORMAT.format(zoom);
120 if (scrollPane.isFitting()) {
121 text = "Fit (" + text + ")";
123 if (!text.equals(zoomSelector.getSelectedItem()))
124 zoomSelector.setSelectedItem(text);
129 private double getPreviousScale(double scale) {
131 for (i = 0; i < ZOOM_LEVELS.length - 1; i++) {
132 if (scale > ZOOM_LEVELS[i] + 0.05 && scale < ZOOM_LEVELS[i + 1] + 0.05)
133 return ZOOM_LEVELS[i];
135 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length / 2]) {
136 // scale is large, drop to next lowest full 100%
137 scale = Math.ceil(scale - 1.05);
138 return Math.max(scale, ZOOM_LEVELS[i]);
145 private double getNextScale(double scale) {
147 for (i = 0; i < ZOOM_LEVELS.length - 1; i++) {
148 if (scale > ZOOM_LEVELS[i] - 0.05 && scale < ZOOM_LEVELS[i + 1] - 0.05)
149 return ZOOM_LEVELS[i + 1];
151 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length / 2]) {
152 // scale is large, give next full 100%
153 scale = Math.floor(scale + 1.05);