source: josm/trunk/src/org/openstreetmap/josm/gui/SplashScreen.java@ 7678

Last change on this file since 7678 was 7321, checked in by Don-vip, 10 years ago

fix #10287 - robustness to system time going backwards during josm startup

  • Property svn:eol-style set to native
File size: 7.7 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.Color;
7import java.awt.Dimension;
8import java.awt.GridBagConstraints;
9import java.awt.GridBagLayout;
10import java.awt.Insets;
11import java.awt.event.MouseAdapter;
12import java.awt.event.MouseEvent;
13import java.util.Arrays;
14import java.util.LinkedList;
15
16import javax.swing.JFrame;
17import javax.swing.JLabel;
18import javax.swing.JPanel;
19import javax.swing.JProgressBar;
20import javax.swing.JSeparator;
21import javax.swing.border.Border;
22import javax.swing.border.EmptyBorder;
23import javax.swing.border.EtchedBorder;
24
25import org.openstreetmap.josm.data.Version;
26import org.openstreetmap.josm.gui.progress.ProgressMonitor;
27import org.openstreetmap.josm.gui.progress.ProgressRenderer;
28import org.openstreetmap.josm.gui.progress.SwingRenderingProgressMonitor;
29import org.openstreetmap.josm.gui.util.GuiHelper;
30import org.openstreetmap.josm.tools.ImageProvider;
31import org.openstreetmap.josm.tools.Utils;
32import org.openstreetmap.josm.tools.WindowGeometry;
33
34/**
35 * Show a splash screen so the user knows what is happening during startup.
36 *
37 */
38public class SplashScreen extends JFrame {
39
40 private final SwingRenderingProgressMonitor progressMonitor;
41
42 /**
43 * Constructs a new {@code SplashScreen}.
44 */
45 public SplashScreen() {
46 super();
47 setUndecorated(true);
48
49 // Add a nice border to the main splash screen
50 JPanel contentPane = (JPanel)this.getContentPane();
51 Border margin = new EtchedBorder(1, Color.white, Color.gray);
52 contentPane.setBorder(margin);
53
54 // Add a margin from the border to the content
55 JPanel innerContentPane = new JPanel();
56 innerContentPane.setBorder(new EmptyBorder(10, 10, 2, 10));
57 contentPane.add(innerContentPane);
58 innerContentPane.setLayout(new GridBagLayout());
59
60 // Add the logo
61 JLabel logo = new JLabel(ImageProvider.get("logo.png"));
62 GridBagConstraints gbc = new GridBagConstraints();
63 gbc.gridheight = 2;
64 gbc.insets = new Insets(0, 0, 0, 70);
65 innerContentPane.add(logo, gbc);
66
67 // Add the name of this application
68 JLabel caption = new JLabel("JOSM – " + tr("Java OpenStreetMap Editor"));
69 caption.setFont(GuiHelper.getTitleFont());
70 gbc.gridheight = 1;
71 gbc.gridx = 1;
72 gbc.insets = new Insets(30, 0, 0, 0);
73 innerContentPane.add(caption, gbc);
74
75 // Add the version number
76 JLabel version = new JLabel(tr("Version {0}", Version.getInstance().getVersionString()));
77 gbc.gridy = 1;
78 gbc.insets = new Insets(0, 0, 0, 0);
79 innerContentPane.add(version, gbc);
80
81 // Add a separator to the status text
82 JSeparator separator = new JSeparator(JSeparator.HORIZONTAL);
83 gbc.gridx = 0;
84 gbc.gridy = 2;
85 gbc.gridwidth = 2;
86 gbc.fill = GridBagConstraints.HORIZONTAL;
87 gbc.insets = new Insets(15, 0, 5, 0);
88 innerContentPane.add(separator, gbc);
89
90 // Add a status message
91 SplashScreenProgressRenderer progressRenderer = new SplashScreenProgressRenderer();
92 gbc.gridy = 3;
93 gbc.insets = new Insets(0, 0, 10, 0);
94 innerContentPane.add(progressRenderer, gbc);
95 progressMonitor = new SwingRenderingProgressMonitor(progressRenderer);
96
97 pack();
98
99 WindowGeometry.centerOnScreen(this.getSize(), "gui.geometry").applySafe(this);
100
101 // Add ability to hide splash screen by clicking it
102 addMouseListener(new MouseAdapter() {
103 @Override
104 public void mousePressed(MouseEvent event) {
105 setVisible(false);
106 }
107 });
108 }
109
110 /**
111 * Returns the progress monitor.
112 * @return The progress monitor
113 */
114 public ProgressMonitor getProgressMonitor() {
115 return progressMonitor;
116 }
117
118 private static class SplashScreenProgressRenderer extends JPanel implements ProgressRenderer {
119 private JLabel lblTaskTitle;
120 private JLabel lblCustomText;
121 private JProgressBar progressBar;
122
123 protected void build() {
124 setLayout(new GridBagLayout());
125 GridBagConstraints gc = new GridBagConstraints();
126 gc.gridx = 0;
127 gc.gridy = 0;
128 gc.fill = GridBagConstraints.HORIZONTAL;
129 gc.weightx = 1.0;
130 gc.weighty = 0.0;
131 gc.insets = new Insets(5,0,0,0);
132 add(lblTaskTitle = new JLabel(" "), gc);
133
134 gc.gridx = 0;
135 gc.gridy = 1;
136 gc.fill = GridBagConstraints.HORIZONTAL;
137 gc.weightx = 1.0;
138 gc.weighty = 0.0;
139 gc.insets = new Insets(5,0,0,0);
140 add(lblCustomText = new JLabel(" ") {
141 @Override
142 public Dimension getPreferredSize() {
143 Dimension d = super.getPreferredSize();
144 if(d.width < 600) d.width = 600;
145 d.height *= MAX_NUMBER_OF_MESSAGES;
146 return d;
147 }
148 }, gc);
149
150 gc.gridx = 0;
151 gc.gridy = 2;
152 gc.fill = GridBagConstraints.HORIZONTAL;
153 gc.weightx = 1.0;
154 gc.weighty = 0.0;
155 gc.insets = new Insets(5,0,0,0);
156 add(progressBar = new JProgressBar(JProgressBar.HORIZONTAL), gc);
157 }
158
159 public SplashScreenProgressRenderer() {
160 build();
161 }
162
163 @Override
164 public void setCustomText(String message) {
165 if(message.isEmpty())
166 message = " "; // prevent killing of additional line
167 lblCustomText.setText(message);
168 repaint();
169 }
170
171 @Override
172 public void setIndeterminate(boolean indeterminate) {
173 progressBar.setIndeterminate(indeterminate);
174 repaint();
175 }
176
177 @Override
178 public void setMaximum(int maximum) {
179 progressBar.setMaximum(maximum);
180 repaint();
181 }
182
183 private static final int MAX_NUMBER_OF_MESSAGES = 3;
184 private LinkedList<String> messages = new LinkedList<>(Arrays.asList("", "", "")); //update when changing MAX_NUMBER_OF_MESSAGES
185 private long time = System.currentTimeMillis();
186
187 /**
188 * Stores and displays the {@code MAX_NUMBER_OF_MESSAGES} most recent
189 * task titles together with their execution time.
190 */
191 @Override
192 public void setTaskTitle(String taskTitle) {
193
194 while (messages.size() >= MAX_NUMBER_OF_MESSAGES) {
195 messages.removeFirst();
196 }
197 long now = System.currentTimeMillis();
198 String prevMessageTitle = messages.getLast();
199 // now should always be >= time but if can be inferior sometimes, see #10287
200 if (!prevMessageTitle.isEmpty() && now >= time) {
201 messages.removeLast();
202 messages.add(tr("{0} ({1})", prevMessageTitle, Utils.getDurationString(now - time)));
203 }
204 time = now;
205 if (!taskTitle.isEmpty()) {
206 messages.add(taskTitle);
207 }
208 StringBuilder html = new StringBuilder();
209 int i = 0;
210 for (String m : messages) {
211 html.append("<p class=\"entry").append(++i).append("\">").append(m).append("</p>");
212 }
213
214 lblTaskTitle.setText("<html><style>"
215 + ".entry1{color:#CCCCCC;}"
216 + ".entry2{color:#999999;}"
217 + ".entry3{color:#000000;}</style>" + html + "</html>"); //update when changing MAX_NUMBER_OF_MESSAGES
218 repaint();
219 }
220
221 @Override
222 public void setValue(int value) {
223 progressBar.setValue(value);
224 repaint();
225 }
226 }
227}
Note: See TracBrowser for help on using the repository browser.