1 package net.sf.openrocket.gui.scalefigure;
3 import java.awt.Component;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.text.DecimalFormat;
7 import java.util.Arrays;
8 import java.util.EventObject;
9 import java.util.Locale;
11 import javax.swing.JButton;
12 import javax.swing.JComboBox;
13 import javax.swing.JPanel;
15 import net.miginfocom.swing.MigLayout;
16 import net.sf.openrocket.gui.util.Icons;
17 import net.sf.openrocket.util.StateChangeListener;
19 public class ScaleSelector extends JPanel {
21 // Ready zoom settings
22 private static final DecimalFormat PERCENT_FORMAT = new DecimalFormat("0.#%");
24 private static final double[] ZOOM_LEVELS = { 0.15, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0 };
25 private static final String ZOOM_FIT = "Fit";
26 private static final String[] ZOOM_SETTINGS;
28 ZOOM_SETTINGS = new String[ZOOM_LEVELS.length + 1];
29 for (int i = 0; i < ZOOM_LEVELS.length; i++)
30 ZOOM_SETTINGS[i] = PERCENT_FORMAT.format(ZOOM_LEVELS[i]);
31 ZOOM_SETTINGS[ZOOM_SETTINGS.length - 1] = ZOOM_FIT;
35 private final ScaleScrollPane scrollPane;
36 private JComboBox zoomSelector;
39 public ScaleSelector(ScaleScrollPane scroll) {
40 super(new MigLayout());
42 this.scrollPane = scroll;
45 JButton button = new JButton(Icons.ZOOM_OUT);
46 button.addActionListener(new ActionListener() {
48 public void actionPerformed(ActionEvent e) {
49 double scale = scrollPane.getScaling();
50 scale = getPreviousScale(scale);
51 scrollPane.setScaling(scale);
56 // Zoom level selector
57 String[] settings = ZOOM_SETTINGS;
58 if (!scrollPane.isFittingAllowed()) {
59 settings = Arrays.copyOf(settings, settings.length - 1);
62 zoomSelector = new JComboBox(settings);
63 zoomSelector.setEditable(true);
65 zoomSelector.addActionListener(new ActionListener() {
67 public void actionPerformed(ActionEvent e) {
69 String text = (String) zoomSelector.getSelectedItem();
70 text = text.replaceAll("%", "").trim();
72 if (text.toLowerCase(Locale.getDefault()).startsWith(ZOOM_FIT.toLowerCase(Locale.getDefault())) &&
73 scrollPane.isFittingAllowed()) {
74 scrollPane.setFitting(true);
79 double n = Double.parseDouble(text);
84 scrollPane.setScaling(n);
86 } catch (NumberFormatException ignore) {
92 scrollPane.getFigure().addChangeListener(new StateChangeListener() {
94 public void stateChanged(EventObject e) {
98 add(zoomSelector, "gap rel");
102 button = new JButton(Icons.ZOOM_IN);
103 button.addActionListener(new ActionListener() {
105 public void actionPerformed(ActionEvent e) {
106 double scale = scrollPane.getScaling();
107 scale = getNextScale(scale);
108 scrollPane.setScaling(scale);
111 add(button, "gapleft rel");
117 private void setZoomText() {
119 double zoom = scrollPane.getScaling();
120 text = PERCENT_FORMAT.format(zoom);
121 if (scrollPane.isFitting()) {
122 text = "Fit (" + text + ")";
124 if (!text.equals(zoomSelector.getSelectedItem()))
125 zoomSelector.setSelectedItem(text);
130 private double getPreviousScale(double scale) {
132 for (i = 0; i < ZOOM_LEVELS.length - 1; i++) {
133 if (scale > ZOOM_LEVELS[i] + 0.05 && scale < ZOOM_LEVELS[i + 1] + 0.05)
134 return ZOOM_LEVELS[i];
136 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length / 2]) {
137 // scale is large, drop to next lowest full 100%
138 scale = Math.ceil(scale - 1.05);
139 return Math.max(scale, ZOOM_LEVELS[i]);
146 private double getNextScale(double scale) {
148 for (i = 0; i < ZOOM_LEVELS.length - 1; i++) {
149 if (scale > ZOOM_LEVELS[i] - 0.05 && scale < ZOOM_LEVELS[i + 1] - 0.05)
150 return ZOOM_LEVELS[i + 1];
152 if (scale > ZOOM_LEVELS[ZOOM_LEVELS.length / 2]) {
153 // scale is large, give next full 100%
154 scale = Math.floor(scale + 1.05);
161 public void setEnabled(boolean b){
162 for ( Component c : getComponents() ){