001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028package edu.wisc.ssec.mcidasv.util; 029 030import static edu.wisc.ssec.mcidasv.util.McVGuiUtils.setButtonImage; 031 032import java.awt.Dimension; 033import java.awt.EventQueue; 034import java.awt.GridBagConstraints; 035import java.awt.GridBagLayout; 036import java.awt.event.ActionEvent; 037import java.awt.event.WindowAdapter; 038import java.awt.event.WindowEvent; 039 040import java.io.IOException; 041 042import javax.swing.GroupLayout; 043import javax.swing.ImageIcon; 044import javax.swing.JButton; 045import javax.swing.JDialog; 046import javax.swing.JFrame; 047import javax.swing.JLabel; 048import javax.swing.JPanel; 049import javax.swing.JScrollPane; 050import javax.swing.JTextPane; 051import javax.swing.LayoutStyle; 052import javax.swing.WindowConstants; 053import javax.swing.event.HyperlinkEvent; 054 055/** 056 * {@code WelcomeWindow} is really just intended to <i>try</i> to detect known 057 * hardware problems and inform the user about any problems. 058 * 059 * <p>The current implementation does not perform <i>any</i> detection, but 060 * expect this to change. 061 */ 062// NOTE TO MCV CODERS: 063// **DOCUMENT WHAT CHECKS AND/OR DETECTION ARE BEING PERFORMED** 064//public class WelcomeWindow extends JFrame { 065public class WelcomeWindow extends JDialog { 066 067 /** Path to {@literal "header"} image. */ 068 private static final String LOGO_PATH = 069 "/edu/wisc/ssec/mcidasv/images/mcidasv_logo.gif"; 070 071 /** Path to the HTML to display within {@link #textPane}. */ 072 private static final String WELCOME_HTML = 073 "/edu/wisc/ssec/mcidasv/resources/welcome.html"; 074 075 /** 076 * Message to display if there was a problem loading 077 * {@link #WELCOME_HTML}. 078 */ 079 private static final String ERROR_MESSAGE = 080 "McIDAS-V had a problem displaying its welcome message. Please" 081 + " contact the McIDAS Help Desk for assistance."; 082 083 /** Dimensions of the welcome window frame. */ 084 private static final Dimension WINDOW_SIZE = new Dimension(495, 431); 085 086 /** Default auto-quit delay (in milliseconds). */ 087 public static final long DEFAULT_QUIT_DELAY = 2500; 088 089 /** Java-friendly location of the path to the welcome message. */ 090 private final java.net.URL contents; 091 092 /** Whether or not the window should automatically close. */ 093 private final boolean autoQuit; 094 095 /** Delay in milliseconds for auto-quitting. */ 096 private final long autoQuitDelay; 097 098 /** 099 * Creates new form WelcomeWindow. 100 */ 101 public WelcomeWindow() { 102 this(false, Long.MAX_VALUE); 103 } 104 105 public WelcomeWindow(boolean autoQuit, long delay) { 106 this.autoQuit = autoQuit; 107 this.autoQuitDelay = delay; 108 this.contents = WelcomeWindow.class.getResource(WELCOME_HTML); 109 initComponents(); 110 } 111 112 /** 113 * This method is called from within the constructor to 114 * initialize the form. 115 * WARNING: Do NOT modify this code. The content of this method is 116 * always regenerated by the Form Editor. 117 */ 118 // <editor-fold defaultstate="collapsed" desc="Generated Code"> 119 private void initComponents() { 120 121 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 122 setTitle("Welcome to McIDAS-V"); 123 setLocationByPlatform(true); 124 addWindowListener(new WindowAdapter() { 125 @Override public void windowClosing(WindowEvent evt) { 126 formWindowClosing(evt); 127 } 128 }); 129 130 logoPanel.setLayout(new GridBagLayout()); 131 132 logoLabel.setIcon(new ImageIcon(getClass().getResource(LOGO_PATH))); // NOI18N 133 logoPanel.add(logoLabel, new GridBagConstraints()); 134 135 textPane.setEditable(false); 136 try { 137 textPane.setPage(contents); 138 } catch (IOException e) { 139 textPane.setText(ERROR_MESSAGE); 140 e.printStackTrace(); 141 } 142 textPane.addHyperlinkListener(this::textPaneHyperlinkUpdate); 143 scrollPane.setViewportView(textPane); 144 145 GroupLayout mainPanelLayout = new GroupLayout(mainPanel); 146 mainPanel.setLayout(mainPanelLayout); 147 mainPanelLayout.setHorizontalGroup( 148 mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 149 .addComponent(scrollPane, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE) 150 ); 151 mainPanelLayout.setVerticalGroup( 152 mainPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 153 .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 273, Short.MAX_VALUE) 154 ); 155 156 setButtonImage(startButton, McVGuiUtils.ICON_APPLY_SMALL); 157 startButton.addActionListener(this::startButtonActionPerformed); 158 159 setButtonImage(quitButton, McVGuiUtils.ICON_CANCEL_SMALL); 160 quitButton.addActionListener(this::quitButtonActionPerformed); 161 162 GroupLayout buttonPanelLayout = new GroupLayout(buttonPanel); 163 buttonPanel.setLayout(buttonPanelLayout); 164 buttonPanelLayout.setHorizontalGroup( 165 buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 166 .addGroup(GroupLayout.Alignment.TRAILING, buttonPanelLayout.createSequentialGroup() 167 .addContainerGap(144, Short.MAX_VALUE) 168 .addComponent(quitButton) 169 .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) 170 .addComponent(startButton)) 171 ); 172 buttonPanelLayout.setVerticalGroup( 173 buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING) 174 .addGroup(buttonPanelLayout.createParallelGroup(GroupLayout.Alignment.BASELINE) 175 .addComponent(startButton) 176 .addComponent(quitButton)) 177 ); 178 179 GroupLayout layout = new GroupLayout(getContentPane()); 180 getContentPane().setLayout(layout); 181 layout.setHorizontalGroup( 182 layout.createParallelGroup(GroupLayout.Alignment.LEADING) 183 .addGroup(layout.createSequentialGroup() 184 .addContainerGap() 185 .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 186 .addComponent(mainPanel, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 187 .addComponent(buttonPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 188 .addComponent(logoPanel, GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE)) 189 .addContainerGap()) 190 ); 191 layout.setVerticalGroup( 192 layout.createParallelGroup(GroupLayout.Alignment.LEADING) 193 .addGroup(layout.createSequentialGroup() 194 .addContainerGap() 195 .addComponent(logoPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 196 .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED) 197 .addComponent(mainPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 198 .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 199 .addComponent(buttonPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 200 .addContainerGap()) 201 ); 202 203 pack(); 204 setLocationRelativeTo(null); 205 setSize(WINDOW_SIZE); 206 setModal(true); 207 }// </editor-fold> 208 209 /** 210 * Show or close the Welcome Window. 211 * 212 * <p>Overridden in McV to handle auto-quitting. If we're supposed to 213 * auto-quit, a thread will be started that calls {@link JButton#doClick()}. 214 * </p> 215 * 216 * @param visible Whether or not the dialog should be opened or closed. 217 */ 218 @Override public void setVisible(boolean visible) { 219 if (autoQuit) { 220 new Thread() { 221 public void run() { 222 try { 223 sleep(autoQuitDelay); 224 } catch (InterruptedException ex) { 225 // not much else to be done... 226 ex.printStackTrace(); 227 } finally { 228 EventQueue.invokeLater(startButton::doClick); 229 } 230 } 231 }.start(); 232 } 233 super.setVisible(visible); 234 } 235 236 /** 237 * Handles the user clicking on {@link #startButton}. 238 * 239 * @param evt Event to handle. Currently ignored. 240 */ 241 private void startButtonActionPerformed(ActionEvent evt) { 242 this.setVisible(false); 243 } 244 245 /** 246 * Handles the user clicking on {@link #quitButton}. Doesn't do anything 247 * aside from handing off things to 248 * {@link #formWindowClosing(WindowEvent)} 249 * 250 * @param evt Event to handle. Currently ignored. 251 * 252 * @see #formWindowClosing(WindowEvent) 253 */ 254 private void quitButtonActionPerformed(ActionEvent evt) { 255 formWindowClosing(null); 256 } 257 258 /** 259 * Handles the user opting to close the welcome window 260 * {@link JFrame}. Executes {@code System.exit(1)} in an 261 * effort to signal to the startup scripts that window terminated 262 * {@literal "abnormally"}. 263 * 264 * <p>An abnormal termination will result in the startup script 265 * terminating the launch of McIDAS-V. 266 * 267 * @param evt Event to handle. Currently ignored. 268 */ 269 private void formWindowClosing(WindowEvent evt) { 270 System.exit(1); 271 } 272 273 /** 274 * Listens to {@link #textPane} in order to handle the user clicking on 275 * HTML links. 276 * 277 * @param evt Event to handle. Anything other than 278 * an {@literal "ACTIVATED"} 279 * {@link javax.swing.event.HyperlinkEvent.EventType HyperlinkEvent.EventType} 280 * is ignored. 281 * 282 * @see WebBrowser#browse(String) 283 */ 284 private void textPaneHyperlinkUpdate(HyperlinkEvent evt) { 285 if (evt.getEventType() != HyperlinkEvent.EventType.ACTIVATED) { 286 return; 287 } 288 289 String url = null; 290 if (evt.getURL() == null) { 291 url = evt.getDescription(); 292 } else { 293 url = evt.getURL().toString(); 294 } 295 296 WebBrowser.browse(url); 297 } 298 299 /** 300 * Kick the tires. 301 * 302 * @param args Command line arguments 303 */ 304 public static void main(String[] args) { 305 EventQueue.invokeLater(() -> { 306 WelcomeWindow ww; 307 if (args.length == 2) { 308 boolean autoQuit = "-autoquit".equals(args[0]); 309 long delay = Long.parseLong(args[1]); 310 ww = new WelcomeWindow(autoQuit, delay); 311 } else if (args.length == 1) { 312 boolean autoQuit = "-autoquit".equals(args[0]); 313 ww = new WelcomeWindow(autoQuit, DEFAULT_QUIT_DELAY); 314 } 315 else { 316 ww = new WelcomeWindow(); 317 } 318 ww.setVisible(true); 319 }); 320 } 321 322 // boring gui components 323 private final JPanel buttonPanel = new JPanel(); 324 private final JLabel logoLabel = new JLabel(); 325 private final JPanel logoPanel = new JPanel(); 326 private final JPanel mainPanel = new JPanel(); 327 private final JButton quitButton = new JButton("Quit"); 328 private final JScrollPane scrollPane = new JScrollPane(); 329 private final JButton startButton = new JButton("Start McIDAS-V"); 330 private final JTextPane textPane = new JTextPane(); 331}