/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2006 Sun Microsystems, Inc. */ package org.opends.quicksetup.ui; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.util.HashMap; import javax.swing.Box; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import javax.swing.text.JTextComponent; import org.opends.quicksetup.installer.FieldName; import org.opends.quicksetup.installer.InstallProgressDescriptor; import org.opends.quicksetup.installer.LabelFieldDescriptor; import org.opends.quicksetup.installer.UserInstallData; import org.opends.quicksetup.uninstaller.UninstallProgressDescriptor; import org.opends.quicksetup.util.HtmlProgressMessageFormatter; import org.opends.quicksetup.util.ProgressMessageFormatter; import org.opends.quicksetup.util.URLWorker; import org.opends.quicksetup.util.Utils; /** * This is an abstract class that is extended by all the classes that are in * the CardLayout of CurrentStepPanel. All the panels that appear on the * top-right side of the dialog extend this class: WelcomePane, ReviewPanel, * etc. * */ public abstract class QuickSetupStepPanel extends QuickSetupPanel implements HyperlinkListener { private Component inputPanel; private ProgressMessageFormatter formatter; // We can use a HashMap (not multi-thread safe) because all // the calls to this object are done in the event-thread. private HashMap hmURLWorkers = new HashMap(); /** * Called just before the panel is shown: used to update the contents of the * panel with new UserData (used in particular in the review panel). * * @param data the new user data. */ public void beginDisplay(UserInstallData data) { } /** * Called just after the panel is shown: used to set focus properly. */ public void endDisplay() { } /** * Called when a progress change must be reflected in the panels. Only * ProgressPanel overwrites this method and for all the others it stays empty. * @param descriptor the descriptor of the Installation progress. */ public void displayProgress(InstallProgressDescriptor descriptor) { } /** * Called when a progress change must be reflected in the panels. Only * ProgressPanel overwrites this method and for all the others it stays empty. * @param descriptor the descriptor of the Uninstallation progress. */ public void displayProgress(UninstallProgressDescriptor descriptor) { } /** * Implements HyperlinkListener. When the user clicks on a link we will * try to display the associated URL in the browser of the user. * * @param e the HyperlinkEvent. */ public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { String url = e.getURL().toString(); if (!isURLWorkerRunning(url)) { /* * Only launch the worker if there is not already a worker trying to * display this URL. */ URLWorker worker = new URLWorker(this, url); startWorker(worker); } } } /** * Returns the value corresponding to the provided FieldName. * @param fieldName the FieldName for which we want to obtain the value. * @return the value corresponding to the provided FieldName. */ public Object getFieldValue(FieldName fieldName) { return null; } /** * Sets the specified value in the field associated with the field name. * @param fieldName the field name associated with the field. * @param value the value that must be set. */ public void setFieldValue(FieldName fieldName, Object value) { } /** * Marks as invalid (or valid depending on the value of the invalid parameter) * a field corresponding to FieldName. This basically implies udpating the * style of the JLabel associated with fieldName (the association is done * using the LabelFieldDescriptor class). * @param fieldName the FieldName to be marked as valid or invalid. * @param invalid whether to mark the field as valid or invalid. */ public void displayFieldInvalid(FieldName fieldName, boolean invalid) { } /** * Returns the minimum width of the panel. This is used to calculate the * minimum widht of the dialog. * @return the minimum width of the panel. */ public int getMinimumWidth() { // Just take the preferred width of the inputPanel because the // instructionsPanel // are too wide. int width = 0; if (inputPanel != null) { width = (int) inputPanel.getPreferredSize().getWidth(); } return width; } /** * Returns the minimum height of the panel. This is used to calculate the * minimum height of the dialog. * @return the minimum height of the panel. */ public int getMinimumHeight() { int height = (int) getPreferredSize().getHeight(); return height; } /** * Creates the layout of the panel. * */ protected void createLayout() { setLayout(new GridBagLayout()); setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); Component titlePanel = createTitlePanel(); Component instructionsPanel = createInstructionsPanel(); inputPanel = createInputPanel(); boolean somethingAdded = false; if (titlePanel != null) { gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets.left = 0; add(titlePanel, gbc); somethingAdded = true; } if (instructionsPanel != null) { if (somethingAdded) { gbc.insets.top = UIFactory.TOP_INSET_INSTRUCTIONS_SUBPANEL; } else { gbc.insets.top = 0; } gbc.insets.left = 0; gbc.weightx = 1.0; gbc.weighty = 0.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTHWEST; add(instructionsPanel, gbc); somethingAdded = true; } if (inputPanel != null) { if (somethingAdded) { gbc.insets.top = UIFactory.TOP_INSET_INPUT_SUBPANEL; } else { gbc.insets.top = 0; } gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets.left = 0; add(inputPanel, gbc); somethingAdded = true; } else { addVerticalGlue(this); } } /** * Commodity method that returns a JTextComponent based on a * LabelFieldDescriptor. * @param desc the LabelFieldDescriptor describing the JTextField. * @param defaultValue the default value used to initialize the * JTextComponent. * @return a JTextComponent based on a * LabelFieldDescriptor. */ protected JTextComponent makeJTextComponent(LabelFieldDescriptor desc, String defaultValue) { JTextComponent field; switch (desc.getType()) { case TEXTFIELD: field = UIFactory.makeJTextField(defaultValue, desc.getTooltip(), desc .getSize(), UIFactory.TextStyle.TEXTFIELD); break; case PASSWORD: field = UIFactory.makeJPasswordField(defaultValue, desc.getTooltip(), desc .getSize(), UIFactory.TextStyle.PASSWORD_FIELD); break; case READ_ONLY: field = UIFactory.makeTextPane(defaultValue, UIFactory.TextStyle.READ_ONLY); break; default: throw new IllegalArgumentException("Unknown type: " + desc.getType()); } return field; } /** * Commodity method that returns a JLabel based on a LabelFieldDescriptor. * @param desc the LabelFieldDescriptor describing the JLabel. * @return a JLabel based on a LabelFieldDescriptor. */ protected JLabel makeJLabel(LabelFieldDescriptor desc) { UIFactory.TextStyle style; if (desc.getLabelType() == LabelFieldDescriptor.LabelType.PRIMARY) { style = UIFactory.TextStyle.PRIMARY_FIELD_VALID; } else { style = UIFactory.TextStyle.SECONDARY_FIELD_VALID; } return UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, desc.getLabel(), style); } /** * Creates and returns the panel that contains the layout specific to the * panel. * @return the panel that contains the layout specific to the * panel. */ protected abstract Component createInputPanel(); /** * Returns the title of this panel. * @return the title of this panel. */ protected abstract String getTitle(); /** * Returns the instruction of this panel. * @return the instruction of this panel. */ protected abstract String getInstructions(); /** * Commodity method that adds a vertical glue at the bottom of a given panel. * @param panel the panel to which we want to add a vertical glue. */ protected void addVerticalGlue(JPanel panel) { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = UIFactory.getEmptyInsets(); gbc.weighty = 1.0; gbc.fill = GridBagConstraints.VERTICAL; panel.add(Box.createVerticalGlue(), gbc); } /** * This method is called by the URLWorker when it has finished its task. * @param worker the URLWorker that finished its task. */ public void urlWorkerFinished(URLWorker worker) { hmURLWorkers.remove(worker.getURL()); } /** * Returns true if this is a WebStart based installer and * false otherwise. * @return true if this is a WebStart based installer and * false otherwise. */ protected boolean isWebStart() { return Utils.isWebStart(); } /** * Returns the formatter that will be used to display the messages in this * panel. * @return the formatter that will be used to display the messages in this * panel. */ ProgressMessageFormatter getFormatter() { if (formatter == null) { formatter = new HtmlProgressMessageFormatter(); } return formatter; } /** * Creates and returns the title panel. * @return the title panel. */ private Component createTitlePanel() { Component titlePanel = null; String title = getTitle(); if (title != null) { JPanel p = new JPanel(new GridBagLayout()); p.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.0; gbc.gridwidth = GridBagConstraints.RELATIVE; JLabel l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title, UIFactory.TextStyle.TITLE); p.add(l, gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; p.add(Box.createHorizontalGlue(), gbc); titlePanel = p; } return titlePanel; } /** * Creates and returns the instructions panel. * @return the instructions panel. */ private Component createInstructionsPanel() { Component instructionsPanel = null; String instructions = getInstructions(); if (instructions != null) { JEditorPane p = UIFactory.makeHtmlPane(instructions, UIFactory.INSTRUCTIONS_FONT); p.setOpaque(false); p.setEditable(false); p.addHyperlinkListener(this); instructionsPanel = p; } return instructionsPanel; } /** * Returns true if there is URLWorker running for the given url * and false otherwise. * @param url the url. * @return true if there is URLWorker running for the given url * and false otherwise. */ private boolean isURLWorkerRunning(String url) { return hmURLWorkers.get(url) != null; } /** * Starts a worker. * @param worker the URLWorker to be started. */ private void startWorker(URLWorker worker) { hmURLWorkers.put(worker.getURL(), worker); worker.startBackgroundTask(); } }