001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.license;
043:
044: import java.awt.BorderLayout;
045: import java.awt.Dimension;
046: import java.awt.FlowLayout;
047: import java.awt.Frame;
048: import java.awt.event.ActionEvent;
049: import java.awt.event.ActionListener;
050: import java.net.URL;
051: import java.util.ResourceBundle;
052: import javax.swing.AbstractButton;
053: import javax.swing.BorderFactory;
054: import javax.swing.JButton;
055: import javax.swing.JDialog;
056: import javax.swing.JPanel;
057:
058: import org.netbeans.util.Util;
059: import org.openide.util.NbBundle;
060: import org.openide.util.Utilities;
061:
062: /**
063: * Displays LicensePanel to user. User must accept license to continue.
064: * if user does not accept license UserCancelException is thrown.
065: *
066: * @author Marek Slama
067: */
068:
069: public final class AcceptLicense {
070:
071: private static JDialog d;
072: private static String command;
073:
074: /** If License was not accepted during installation user must accept it here.
075: */
076: public static void showLicensePanel() throws Exception {
077: Util.setDefaultLookAndFeel();
078: URL url = AcceptLicense.class.getResource("LICENSE.txt"); // NOI18N
079: LicensePanel licensePanel = new LicensePanel(url);
080: ResourceBundle bundle = NbBundle.getBundle(AcceptLicense.class);
081: String yesLabel = bundle.getString("MSG_LicenseYesButton");
082: String noLabel = bundle.getString("MSG_LicenseNoButton");
083: JButton yesButton = new JButton();
084: JButton noButton = new JButton();
085: setLocalizedText(yesButton, yesLabel);
086: setLocalizedText(noButton, noLabel);
087: ActionListener listener = new ActionListener() {
088: public void actionPerformed(ActionEvent e) {
089: command = e.getActionCommand();
090: d.setVisible(false);
091: d = null;
092: }
093: };
094: yesButton.addActionListener(listener);
095: noButton.addActionListener(listener);
096:
097: yesButton.setActionCommand("yes"); // NOI18N
098: noButton.setActionCommand("no"); // NOI18N
099:
100: yesButton.getAccessibleContext().setAccessibleName(
101: bundle.getString("ACSN_AcceptButton"));
102: yesButton.getAccessibleContext().setAccessibleName(
103: bundle.getString("ACSD_AcceptButton"));
104:
105: noButton.getAccessibleContext().setAccessibleName(
106: bundle.getString("ACSN_RejectButton"));
107: noButton.getAccessibleContext().setAccessibleName(
108: bundle.getString("ACSD_RejectButton"));
109:
110: Dimension yesPF = yesButton.getPreferredSize();
111: Dimension noPF = noButton.getPreferredSize();
112: int maxWidth = Math.max(yesButton.getPreferredSize().width,
113: noButton.getPreferredSize().width);
114: int maxHeight = Math.max(yesButton.getPreferredSize().height,
115: noButton.getPreferredSize().height);
116: yesButton.setPreferredSize(new Dimension(maxWidth, maxHeight));
117: noButton.setPreferredSize(new Dimension(maxWidth, maxHeight));
118:
119: d = new JDialog((Frame) null, bundle
120: .getString("MSG_LicenseDlgTitle"), true);
121:
122: d.getAccessibleContext().setAccessibleName(
123: bundle.getString("ACSN_LicenseDlg"));
124: d.getAccessibleContext().setAccessibleDescription(
125: bundle.getString("ACSD_LicenseDlg"));
126:
127: d.getContentPane().add(licensePanel, BorderLayout.CENTER);
128: JPanel buttonPanel = new JPanel();
129: buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
130: buttonPanel.setBorder(BorderFactory.createEmptyBorder(17, 12,
131: 11, 11));
132: buttonPanel.add(yesButton);
133: buttonPanel.add(noButton);
134: d.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
135: d.setSize(new Dimension(600, 600));
136: d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
137: d.setModal(true);
138: d.setResizable(true);
139: //Center on screen
140: d.setLocationRelativeTo(null);
141: d.setVisible(true);
142:
143: if ("yes".equals(command)) { // NOI18N
144: return;
145: } else {
146: throw new org.openide.util.UserCancelException();
147: }
148: }
149:
150: /**
151: * Actual setter of the text & mnemonics for the AbstractButton or
152: * their subclasses. We must copy necessary code from org.openide.awt.Mnemonics
153: * because org.openide.awt module is not available yet when this code is called.
154: * @param item AbstractButton
155: * @param text new label
156: */
157: private static void setLocalizedText(AbstractButton button,
158: String text) {
159: if (text == null) {
160: button.setText(null);
161: return;
162: }
163:
164: int i = findMnemonicAmpersand(text);
165:
166: if (i < 0) {
167: // no '&' - don't set the mnemonic
168: button.setText(text);
169: button.setMnemonic(0);
170: } else {
171: button
172: .setText(text.substring(0, i)
173: + text.substring(i + 1));
174:
175: if (Utilities.isMac()) {
176: // there shall be no mnemonics on macosx.
177: //#55864
178: return;
179: }
180:
181: char ch = text.charAt(i + 1);
182:
183: // it's latin character or arabic digit,
184: // setting it as mnemonics
185: button.setMnemonic(ch);
186:
187: // If it's something like "Save &As", we need to set another
188: // mnemonic index (at least under 1.4 or later)
189: // see #29676
190: button.setDisplayedMnemonicIndex(i);
191: }
192: }
193:
194: /**
195: * Searches for an ampersand in a string which indicates a mnemonic.
196: * Recognizes the following cases:
197: * <ul>
198: * <li>"Drag & Drop", "Ampersand ('&')" - don't have mnemonic ampersand.
199: * "&" is not found before " " (space), or if enclosed in "'"
200: * (single quotation marks).
201: * <li>"&File", "Save &As..." - do have mnemonic ampersand.
202: * <li>"Rock & Ro&ll", "Underline the '&' &character" - also do have
203: * mnemonic ampersand, but the second one.
204: * </ul>
205: * @param text text to search
206: * @return the position of mnemonic ampersand in text, or -1 if there is none
207: */
208: public static int findMnemonicAmpersand(String text) {
209: int i = -1;
210:
211: do {
212: // searching for the next ampersand
213: i = text.indexOf('&', i + 1);
214:
215: if ((i >= 0) && ((i + 1) < text.length())) {
216: // before ' '
217: if (text.charAt(i + 1) == ' ') {
218: continue;
219:
220: // before ', and after '
221: } else if ((text.charAt(i + 1) == '\'') && (i > 0)
222: && (text.charAt(i - 1) == '\'')) {
223: continue;
224: }
225:
226: // ampersand is marking mnemonics
227: return i;
228: }
229: } while (i >= 0);
230:
231: return -1;
232: }
233: }
|