source: josm/trunk/src/org/openstreetmap/josm/gui/MainFrame.java@ 13651

Last change on this file since 13651 was 13647, checked in by Don-vip, 6 years ago

see #16204 - Allow to start and close JOSM in WebStart sandbox mode (where every external access is denied). This was very useful to reproduce some very tricky bugs that occured in real life but were almost impossible to diagnose.

  • Property svn:eol-style set to native
File size: 8.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BorderLayout;
7import java.awt.Component;
8import java.awt.Image;
9import java.awt.Rectangle;
10import java.awt.Toolkit;
11import java.awt.event.ComponentEvent;
12import java.awt.event.ComponentListener;
13import java.awt.event.WindowAdapter;
14import java.awt.event.WindowEvent;
15import java.beans.PropertyChangeListener;
16import java.util.LinkedList;
17import java.util.List;
18
19import javax.swing.ImageIcon;
20import javax.swing.JFrame;
21import javax.swing.JPanel;
22
23import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
24import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
25import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
26import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
27import org.openstreetmap.josm.gui.layer.OsmDataLayer;
28import org.openstreetmap.josm.gui.layer.OsmDataLayer.LayerStateChangeListener;
29import org.openstreetmap.josm.gui.util.WindowGeometry;
30import org.openstreetmap.josm.spi.preferences.Config;
31import org.openstreetmap.josm.tools.ImageProvider;
32import org.openstreetmap.josm.tools.Logging;
33
34/**
35 * This is the JOSM main window. It updates it's title.
36 * @author Michael Zangl
37 * @since 10340
38 */
39public class MainFrame extends JFrame {
40 private final transient LayerStateChangeListener updateTitleOnLayerStateChange = (layer, newValue) -> onLayerChange(layer);
41
42 private final transient PropertyChangeListener updateTitleOnSaveChange = evt -> {
43 if (evt.getPropertyName().equals(OsmDataLayer.REQUIRES_SAVE_TO_DISK_PROP)
44 || evt.getPropertyName().equals(OsmDataLayer.REQUIRES_UPLOAD_TO_SERVER_PROP)) {
45 OsmDataLayer layer = (OsmDataLayer) evt.getSource();
46 onLayerChange(layer);
47 }
48 };
49
50 protected transient WindowGeometry geometry;
51 protected int windowState = JFrame.NORMAL;
52 private final MainPanel panel;
53 private MainMenu menu;
54
55 /**
56 * Create a new main window.
57 */
58 public MainFrame() {
59 this(new WindowGeometry(new Rectangle(10, 10, 500, 500)));
60 }
61
62 /**
63 * Create a new main window. The parameter will be removed in the future.
64 * @param geometry The inital geometry to use.
65 * @since 12127
66 */
67 public MainFrame(WindowGeometry geometry) {
68 super();
69 this.geometry = geometry;
70 this.panel = new MainPanel(MainApplication.getLayerManager());
71 setContentPane(new JPanel(new BorderLayout()));
72 }
73
74 /**
75 * Initializes the content of the window and get the current status panel.
76 */
77 public void initialize() {
78 menu = new MainMenu();
79 addComponentListener(new WindowPositionSizeListener());
80 addWindowStateListener(new WindowPositionSizeListener());
81
82 setJMenuBar(menu);
83 geometry.applySafe(this);
84 List<Image> l = new LinkedList<>();
85 for (String file : new String[] {
86 "logo_16x16x32", "logo_16x16x8", "logo_32x32x32", "logo_32x32x8", "logo_48x48x32", "logo_48x48x8", "logo"}) {
87 ImageIcon img = ImageProvider.getIfAvailable(file);
88 if (img != null) {
89 l.add(img.getImage());
90 }
91 }
92 setIconImages(l);
93 addWindowListener(new ExitWindowAdapter());
94 setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
95
96 // This listener is never removed, since the main frame exists forever.
97 MainApplication.getLayerManager().addActiveLayerChangeListener(e -> refreshTitle());
98 MainApplication.getLayerManager().addAndFireLayerChangeListener(new ManageLayerListeners());
99
100 refreshTitle();
101
102 getContentPane().add(panel, BorderLayout.CENTER);
103 menu.initialize();
104 }
105
106 /**
107 * Stores the current state of the main frame.
108 */
109 public void storeState() {
110 if (geometry != null) {
111 geometry.remember("gui.geometry");
112 }
113 Config.getPref().putBoolean("gui.maximized", (windowState & JFrame.MAXIMIZED_BOTH) != 0);
114 }
115
116 /**
117 * Gets the main menu used for this window.
118 * @return The main menu.
119 * @throws IllegalStateException if the main frame has not been initialized yet
120 * @see #initialize
121 */
122 public MainMenu getMenu() {
123 if (menu == null) {
124 throw new IllegalStateException("Not initialized.");
125 }
126 return menu;
127 }
128
129 /**
130 * Gets the main panel.
131 * @return The main panel.
132 * @since 12125
133 */
134 public MainPanel getPanel() {
135 return panel;
136 }
137
138 /**
139 * Sets this frame to be maximized.
140 * @param maximized <code>true</code> if the window should be maximized.
141 */
142 public void setMaximized(boolean maximized) {
143 if (maximized) {
144 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
145 windowState = JFrame.MAXIMIZED_BOTH;
146 setExtendedState(windowState);
147 } else {
148 Logging.debug("Main window: maximizing not supported");
149 }
150 } else {
151 throw new UnsupportedOperationException("Unimplemented.");
152 }
153 }
154
155 /**
156 * Update the title of the window to reflect the current content.
157 */
158 public void refreshTitle() {
159 OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
160 boolean dirty = editLayer != null && (editLayer.requiresSaveToFile()
161 || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
162 setTitle((dirty ? "* " : "") + tr("Java OpenStreetMap Editor"));
163 getRootPane().putClientProperty("Window.documentModified", dirty);
164 }
165
166 private void onLayerChange(OsmDataLayer layer) {
167 if (layer == MainApplication.getLayerManager().getEditLayer()) {
168 refreshTitle();
169 }
170 }
171
172 static final class ExitWindowAdapter extends WindowAdapter {
173 @Override
174 public void windowClosing(final WindowEvent evt) {
175 MainApplication.exitJosm(true, 0, null);
176 }
177 }
178
179 /**
180 * Manages the layer listeners, adds them to every layer.
181 */
182 private final class ManageLayerListeners implements LayerChangeListener {
183 @Override
184 public void layerAdded(LayerAddEvent e) {
185 if (e.getAddedLayer() instanceof OsmDataLayer) {
186 OsmDataLayer osmDataLayer = (OsmDataLayer) e.getAddedLayer();
187 osmDataLayer.addLayerStateChangeListener(updateTitleOnLayerStateChange);
188 }
189 e.getAddedLayer().addPropertyChangeListener(updateTitleOnSaveChange);
190 }
191
192 @Override
193 public void layerRemoving(LayerRemoveEvent e) {
194 if (e.getRemovedLayer() instanceof OsmDataLayer) {
195 OsmDataLayer osmDataLayer = (OsmDataLayer) e.getRemovedLayer();
196 osmDataLayer.removeLayerStateChangeListener(updateTitleOnLayerStateChange);
197 }
198 e.getRemovedLayer().removePropertyChangeListener(updateTitleOnSaveChange);
199 }
200
201 @Override
202 public void layerOrderChanged(LayerOrderChangeEvent e) {
203 // not used
204 }
205 }
206
207 private class WindowPositionSizeListener extends WindowAdapter implements ComponentListener {
208 @Override
209 public void windowStateChanged(WindowEvent e) {
210 windowState = e.getNewState();
211 }
212
213 @Override
214 public void componentHidden(ComponentEvent e) {
215 // Do nothing
216 }
217
218 @Override
219 public void componentMoved(ComponentEvent e) {
220 handleComponentEvent(e);
221 }
222
223 @Override
224 public void componentResized(ComponentEvent e) {
225 handleComponentEvent(e);
226 }
227
228 @Override
229 public void componentShown(ComponentEvent e) {
230 // Do nothing
231 }
232
233 private void handleComponentEvent(ComponentEvent e) {
234 Component c = e.getComponent();
235 if (c instanceof JFrame && c.isVisible()) {
236 if (windowState == JFrame.NORMAL) {
237 geometry = new WindowGeometry((JFrame) c);
238 } else {
239 geometry.fixScreen((JFrame) c);
240 }
241 }
242 }
243 }
244
245}
Note: See TracBrowser for help on using the repository browser.