001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Color; 007 import java.awt.Dimension; 008 import java.awt.Font; 009 import java.awt.GridBagConstraints; 010 import java.awt.GridBagLayout; 011 import java.awt.Insets; 012 import java.awt.event.MouseAdapter; 013 import java.awt.event.MouseEvent; 014 015 import java.util.Arrays; 016 import java.util.LinkedList; 017 import javax.swing.JFrame; 018 import javax.swing.JLabel; 019 import javax.swing.JPanel; 020 import javax.swing.JProgressBar; 021 import javax.swing.JSeparator; 022 import javax.swing.border.Border; 023 import javax.swing.border.EmptyBorder; 024 import javax.swing.border.EtchedBorder; 025 026 import org.openstreetmap.josm.data.Version; 027 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 028 import org.openstreetmap.josm.gui.progress.ProgressRenderer; 029 import org.openstreetmap.josm.gui.progress.SwingRenderingProgressMonitor; 030 import org.openstreetmap.josm.tools.ImageProvider; 031 import org.openstreetmap.josm.tools.WindowGeometry; 032 033 /** 034 * Show a splash screen so the user knows what is happening during startup. 035 * 036 */ 037 public class SplashScreen extends JFrame { 038 039 private SplashScreenProgressRenderer progressRenderer; 040 private SwingRenderingProgressMonitor progressMonitor; 041 042 public SplashScreen() { 043 super(); 044 setUndecorated(true); 045 046 // Add a nice border to the main splash screen 047 JPanel contentPane = (JPanel)this.getContentPane(); 048 Border margin = new EtchedBorder(1, Color.white, Color.gray); 049 contentPane.setBorder(margin); 050 051 // Add a margin from the border to the content 052 JPanel innerContentPane = new JPanel(); 053 innerContentPane.setBorder(new EmptyBorder(10, 10, 2, 10)); 054 contentPane.add(innerContentPane); 055 innerContentPane.setLayout(new GridBagLayout()); 056 057 // Add the logo 058 JLabel logo = new JLabel(ImageProvider.get("logo.png")); 059 GridBagConstraints gbc = new GridBagConstraints(); 060 gbc.gridheight = 2; 061 gbc.insets = new Insets(0, 0, 0, 70); 062 innerContentPane.add(logo, gbc); 063 064 // Add the name of this application 065 JLabel caption = new JLabel("JOSM - " + tr("Java OpenStreetMap Editor")); 066 caption.setFont(new Font("Helvetica", Font.BOLD, 20)); 067 gbc.gridheight = 1; 068 gbc.gridx = 1; 069 gbc.insets = new Insets(30, 0, 0, 0); 070 innerContentPane.add(caption, gbc); 071 072 // Add the version number 073 JLabel version = new JLabel(tr("Version {0}", Version.getInstance().getVersionString())); 074 gbc.gridy = 1; 075 gbc.insets = new Insets(0, 0, 0, 0); 076 innerContentPane.add(version, gbc); 077 078 // Add a separator to the status text 079 JSeparator separator = new JSeparator(JSeparator.HORIZONTAL); 080 gbc.gridx = 0; 081 gbc.gridy = 2; 082 gbc.gridwidth = 2; 083 gbc.fill = GridBagConstraints.HORIZONTAL; 084 gbc.insets = new Insets(15, 0, 5, 0); 085 innerContentPane.add(separator, gbc); 086 087 // Add a status message 088 progressRenderer = new SplashScreenProgressRenderer(); 089 gbc.gridy = 3; 090 gbc.insets = new Insets(0, 0, 10, 0); 091 innerContentPane.add(progressRenderer, gbc); 092 progressMonitor = new SwingRenderingProgressMonitor(progressRenderer); 093 094 pack(); 095 096 WindowGeometry.centerOnScreen(this.getSize(), "gui.geometry").applySafe(this); 097 098 // Add ability to hide splash screen by clicking it 099 addMouseListener(new MouseAdapter() { 100 @Override 101 public void mousePressed(MouseEvent event) { 102 setVisible(false); 103 } 104 }); 105 } 106 107 public ProgressMonitor getProgressMonitor() { 108 return progressMonitor; 109 } 110 111 static private class SplashScreenProgressRenderer extends JPanel implements ProgressRenderer { 112 private JLabel lblTaskTitle; 113 private JLabel lblCustomText; 114 private JProgressBar progressBar; 115 116 protected void build() { 117 setLayout(new GridBagLayout()); 118 GridBagConstraints gc = new GridBagConstraints(); 119 gc.gridx = 0; 120 gc.gridy = 0; 121 gc.fill = GridBagConstraints.HORIZONTAL; 122 gc.weightx = 1.0; 123 gc.weighty = 0.0; 124 gc.insets = new Insets(5,0,0,0); 125 add(lblTaskTitle = new JLabel(" "), gc); 126 127 gc.gridx = 0; 128 gc.gridy = 1; 129 gc.fill = GridBagConstraints.HORIZONTAL; 130 gc.weightx = 1.0; 131 gc.weighty = 0.0; 132 gc.insets = new Insets(5,0,0,0); 133 add(lblCustomText = new JLabel(" ") { 134 @Override 135 public Dimension getPreferredSize() { 136 Dimension d = super.getPreferredSize(); 137 if(d.width < 600) d.width = 600; 138 d.height *= MAX_NUMBER_OF_MESSAGES; 139 return d; 140 } 141 }, gc); 142 143 gc.gridx = 0; 144 gc.gridy = 2; 145 gc.fill = GridBagConstraints.HORIZONTAL; 146 gc.weightx = 1.0; 147 gc.weighty = 0.0; 148 gc.insets = new Insets(5,0,0,0); 149 add(progressBar = new JProgressBar(JProgressBar.HORIZONTAL), gc); 150 } 151 152 public SplashScreenProgressRenderer() { 153 build(); 154 } 155 156 public void setCustomText(String message) { 157 if(message.isEmpty()) 158 message = " "; /* prevent killing of additional line */ 159 lblCustomText.setText(message); 160 repaint(); 161 } 162 163 public void setIndeterminate(boolean indeterminate) { 164 progressBar.setIndeterminate(indeterminate); 165 repaint(); 166 } 167 168 public void setMaximum(int maximum) { 169 progressBar.setMaximum(maximum); 170 repaint(); 171 } 172 173 private static final int MAX_NUMBER_OF_MESSAGES = 3; 174 private LinkedList<String> messages = new LinkedList<String>(Arrays.asList("", "", "")); //update when changing MAX_NUMBER_OF_MESSAGES 175 private long time = System.currentTimeMillis(); 176 177 /** 178 * Stores and displays the {@code MAX_NUMBER_OF_MESSAGES} most recent 179 * task titles together with their execution time. 180 */ 181 public void setTaskTitle(String taskTitle) { 182 183 while (messages.size() >= MAX_NUMBER_OF_MESSAGES) { 184 messages.removeFirst(); 185 } 186 long now = System.currentTimeMillis(); 187 String prevMessageTitle = messages.getLast(); 188 if (!prevMessageTitle.isEmpty()) { 189 messages.removeLast(); 190 messages.add(tr("{0} ({1} ms)", prevMessageTitle, Long.toString(now - time))); 191 } 192 time = now; 193 if (!taskTitle.isEmpty()) { 194 messages.add(taskTitle); 195 } 196 String html = ""; 197 int i = 0; 198 for (String m : messages) { 199 html += "<p class=\"entry" + (++i) + "\">" + m + "</p>"; 200 } 201 202 lblTaskTitle.setText("<html><style>" 203 + ".entry1{color:#CCCCCC;}" 204 + ".entry2{color:#999999;}" 205 + ".entry3{color:#000000;}</style>" + html + "</html>"); //update when changing MAX_NUMBER_OF_MESSAGES 206 repaint(); 207 } 208 209 public void setValue(int value) { 210 progressBar.setValue(value); 211 repaint(); 212 } 213 } 214 }