001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2006-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2014-2015 ForgeRock AS 026 */ 027package org.opends.quicksetup.ui; 028 029import org.forgerock.i18n.LocalizableMessage; 030import static com.forgerock.opendj.util.OperatingSystem.isMacOS; 031 032import javax.swing.*; 033import javax.swing.text.JTextComponent; 034import java.awt.*; 035import java.util.StringTokenizer; 036 037/** 038 * A set of utilities specific to GUI QuickSetup applications. 039 */ 040public class Utilities { 041 042 /** 043 * Creates a panel with a field and a browse button. 044 * @param lbl JLabel for the field 045 * @param tf JTextField for holding the browsed data 046 * @param but JButton for invoking browse action 047 * @return the created panel. 048 */ 049 public static JPanel createBrowseButtonPanel(JLabel lbl, 050 JTextComponent tf, 051 JButton but) 052 { 053 GridBagConstraints gbc = new GridBagConstraints(); 054 055 JPanel panel = UIFactory.makeJPanel(); 056 panel.setLayout(new GridBagLayout()); 057 058 gbc.insets = UIFactory.getEmptyInsets(); 059 gbc.gridwidth = 4; 060 gbc.weightx = 0.0; 061 gbc.fill = GridBagConstraints.HORIZONTAL; 062 panel.add(lbl, gbc); 063 064 gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD; 065 gbc.gridwidth--; 066 gbc.weightx = 0.1; 067 panel.add(tf, gbc); 068 069 gbc.insets.left = UIFactory.LEFT_INSET_BROWSE; 070 gbc.gridwidth = GridBagConstraints.RELATIVE; 071 panel.add(but, gbc); 072 073 gbc.weightx = 1.0; 074 gbc.gridwidth = GridBagConstraints.REMAINDER; 075 panel.add(Box.createHorizontalGlue(), gbc); 076 077 return panel; 078 } 079 080 /** 081 * Sets a frames image icon to the standard OpenDS icon appropriate 082 * for the running platform. 083 * 084 * @param frame for which the icon will be set 085 */ 086 public static void setFrameIcon(JFrame frame) 087 { 088 UIFactory.IconType ic; 089 if (isMacOS()) { 090 ic = UIFactory.IconType.MINIMIZED_MAC; 091 } else { 092 ic = UIFactory.IconType.MINIMIZED; 093 } 094 frame.setIconImage(UIFactory.getImageIcon(ic).getImage()); 095 } 096 097 /** 098 * Center the component location based on its preferred size. The code 099 * considers the particular case of 2 screens and puts the component on the 100 * center of the left screen 101 * 102 * @param comp the component to be centered. 103 */ 104 public static void centerOnScreen(Component comp) 105 { 106 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 107 108 int width = (int) comp.getPreferredSize().getWidth(); 109 int height = (int) comp.getPreferredSize().getHeight(); 110 111 boolean multipleScreen = screenSize.width / screenSize.height >= 2; 112 113 if (multipleScreen) 114 { 115 comp.setLocation(screenSize.width / 4 - width / 2, 116 (screenSize.height - height) / 2); 117 } else 118 { 119 comp.setLocation((screenSize.width - width) / 2, 120 (screenSize.height - height) / 2); 121 } 122 } 123 124 /** 125 * Center the component location of the ref component. 126 * 127 * @param comp the component to be centered. 128 * @param ref the component to be used as reference. 129 * 130 */ 131 public static void centerOnComponent(Window comp, Component ref) 132 { 133 comp.setLocationRelativeTo(ref); 134 } 135 136 /** 137 * Displays a confirmation message dialog. 138 * 139 * @param parent 140 * the parent frame of the confirmation dialog. 141 * @param msg 142 * the confirmation message. 143 * @param title 144 * the title of the dialog. 145 * @return <CODE>true</CODE> if the user confirms the message, or 146 * <CODE>false</CODE> if not. 147 */ 148 public static boolean displayConfirmation(Component parent, LocalizableMessage msg, 149 LocalizableMessage title) 150 { 151 return JOptionPane.YES_OPTION == JOptionPane.showOptionDialog( 152 parent, wrapMsg(String.valueOf(msg), 100), String.valueOf(title), 153 JOptionPane.YES_NO_OPTION, 154 JOptionPane.QUESTION_MESSAGE, 155 null, // don't use a custom Icon 156 null, // the titles of buttons 157 null); // default button title 158 } 159 160 /** 161 * Displays an error message dialog. 162 * 163 * @param parent 164 * the parent component of the error dialog. 165 * @param msg 166 * the error message. 167 * @param title 168 * the title for the dialog. 169 */ 170 public static void displayError(Component parent, LocalizableMessage msg, LocalizableMessage title) 171 { 172 JOptionPane.showMessageDialog(parent, 173 wrapMsg(String.valueOf(msg), 100), 174 String.valueOf(title), JOptionPane.ERROR_MESSAGE); 175 } 176 177 /** 178 * Displays an information message dialog. 179 * 180 * @param parent 181 * the parent frame of the information dialog. 182 * @param msg 183 * the error message. 184 * @param title 185 * the title for the dialog. 186 */ 187 public static void displayInformationMessage(JFrame parent, LocalizableMessage msg, 188 LocalizableMessage title) 189 { 190 JOptionPane.showMessageDialog(parent, 191 wrapMsg(String.valueOf(msg), 100), String.valueOf(title), 192 JOptionPane.INFORMATION_MESSAGE); 193 } 194 195 /** 196 * Private method used to wrap the messages that are displayed in dialogs 197 * of type JOptionPane. 198 * @param msg the message. 199 * @param width the maximum width of the column. 200 * @return the wrapped message. 201 */ 202 public static String wrapMsg(String msg, int width) 203 { 204 StringBuilder buffer = new StringBuilder(); 205 StringTokenizer lineTokenizer = new StringTokenizer(msg, "\n", true); 206 while (lineTokenizer.hasMoreTokens()) 207 { 208 String line = lineTokenizer.nextToken(); 209 if (line.equals("\n")) 210 { 211 // It's an end-of-line character, so append it as-is. 212 buffer.append(line); 213 } 214 else if (line.length() < width) 215 { 216 // The line fits in the specified width, so append it as-is. 217 buffer.append(line); 218 } 219 else 220 { 221 // The line doesn't fit in the specified width, so it needs to be 222 // wrapped. Do so at space boundaries. 223 StringBuilder lineBuffer = new StringBuilder(); 224 StringBuilder delimBuffer = new StringBuilder(); 225 StringTokenizer wordTokenizer = new StringTokenizer(line, " ", true); 226 while (wordTokenizer.hasMoreTokens()) 227 { 228 String word = wordTokenizer.nextToken(); 229 if (word.equals(" ")) 230 { 231 // It's a space, so add it to the delim buffer only if the line 232 // buffer is not empty. 233 if (lineBuffer.length() > 0) 234 { 235 delimBuffer.append(word); 236 } 237 } 238 else if (word.length() > width) 239 { 240 // This is a long word that can't be wrapped, so we'll just have to 241 // make do. 242 if (lineBuffer.length() > 0) 243 { 244 buffer.append(lineBuffer); 245 buffer.append("\n"); 246 lineBuffer = new StringBuilder(); 247 } 248 buffer.append(word); 249 250 if (wordTokenizer.hasMoreTokens()) 251 { 252 // The next token must be a space, so remove it. If there are 253 // still more tokens after that, then append an EOL. 254 wordTokenizer.nextToken(); 255 if (wordTokenizer.hasMoreTokens()) 256 { 257 buffer.append("\n"); 258 } 259 } 260 261 if (delimBuffer.length() > 0) 262 { 263 delimBuffer = new StringBuilder(); 264 } 265 } 266 else 267 { 268 // It's not a space, so see if we can fit it on the current line. 269 int newLineLength = lineBuffer.length() + delimBuffer.length() + 270 word.length(); 271 if (newLineLength < width) 272 { 273 // It does fit on the line, so add it. 274 lineBuffer.append(delimBuffer).append(word); 275 } 276 else 277 { 278 // It doesn't fit on the line, so end the current line and start 279 // a new one. 280 buffer.append(lineBuffer); 281 buffer.append("\n"); 282 283 lineBuffer = new StringBuilder(); 284 lineBuffer.append(word); 285 } 286 287 if (delimBuffer.length() > 0) 288 { 289 delimBuffer = new StringBuilder(); 290 } 291 } 292 } 293 294 // If there's anything left in the line buffer, then add it to the 295 // final buffer. 296 buffer.append(lineBuffer); 297 } 298 } 299 return buffer.toString(); 300 } 301}