001/*******************************************************************************
002
003        File:           StandardMacAboutFrame.java
004        Author:         Steve Roy <steve@sillybit.com>
005                                
006        Part of MRJ Adapter, a unified API for easy integration of Mac OS specific
007        functionality within your cross-platform Java application.
008        
009        This library is open source and can be modified and/or distributed under
010        the terms of the Artistic License.
011        <http://mrjadapter.dev.java.net/license.html>
012        
013        Change History:
014        02/20/04        Created this header - Steve
015        04/20/04    Fixed setCredits() to set the caret position to 0 and to
016                                accept null text - Steve
017        08/12/04        Added setCreditsPreferredSize() - Steve
018        11/13/07        Added null check for bo in the credits section - Sciss
019
020*******************************************************************************/
021
022package jahuwaldt.swing;
023
024import javax.swing.BorderFactory;
025import javax.swing.Icon;
026import javax.swing.JEditorPane;
027import javax.swing.JFrame;
028import javax.swing.JLabel;
029import javax.swing.JPanel;
030import javax.swing.JScrollPane;
031import javax.swing.JTextArea;
032import javax.swing.border.Border;
033import javax.swing.event.HyperlinkListener;
034import java.awt.Dimension;
035import java.awt.Font;
036import java.awt.GridBagConstraints;
037import java.awt.GridBagLayout;
038import java.awt.Insets;
039
040/**
041 * Java and cross-platform implementation of an About box similar to the
042 * standard About panel built into the Cocoa framework on Mac OS X. This
043 * implementation is based on a <code>JFrame</code>. It centers itself
044 * automatically on the screen and supports credits in RTF, HTML or plain
045 * text formats.
046 * 
047 * MRJ Adapter 1.2 version
048 * @version December 9, 2023, JAH
049 */
050public class StandardMacAboutFrame extends JFrame
051{
052        /**
053         * The label holding the application icon.
054         */
055        private final JLabel applicationIconLabel;
056        
057        /**
058         * The field holding the application name.
059         */
060        private final JTextArea applicationNameField;
061        
062        /**
063         * The field holding the version string.
064         */
065        private final JTextArea versionField;
066        
067        /**
068         * The field displaying the credits.
069         */
070        private final JEditorPane creditsField;
071        
072        /**
073         * The scroll pane that holds the credits field.
074         */
075        private final JScrollPane creditsScrollPane;
076        
077        /**
078         * The field displaying the copyright string.
079         */
080        private final JTextArea copyrightField;
081        
082        /**
083         * The version string of the application.
084         */
085        private String applicationVersion;
086        
087        /**
088         * The version string of the build.
089         */
090        private String buildVersion;
091        
092        /**
093         * The hyperlink listener for the credits field, for when its content type
094         * is text/html.
095         */
096        private HyperlinkListener hyperlinkListener;
097        
098        /**
099         * Construct a standard Mac about frame.
100         * @param applicationName the name of the application
101         * @param applicationVersion the version string of the application
102         */
103    @SuppressWarnings("OverridableMethodCallInConstructor")
104        public StandardMacAboutFrame(String applicationName, String applicationVersion)
105        {
106                super();
107                setResizable(false);
108                setDefaultCloseOperation(DISPOSE_ON_CLOSE);
109                
110                JPanel c = (JPanel)getContentPane();
111                c.setLayout(new GridBagLayout());
112                
113                GridBagConstraints gbc = new GridBagConstraints();
114                gbc.weightx = 100;
115                gbc.insets.top = 5;
116                gbc.insets.bottom = 5;
117                
118                // Application icon
119                gbc.gridy = 0;
120                applicationIconLabel = new JLabel();
121                c.add(applicationIconLabel, gbc);
122                
123                // Application name
124                gbc.gridy = 1;
125                applicationNameField = new JTextArea("java");
126                applicationNameField.setEditable(false);
127                applicationNameField.setOpaque(false);
128                applicationNameField.setFont(new Font("Lucida Grande", Font.BOLD, 14));
129                c.add(applicationNameField, gbc);
130                
131                // Version
132                gbc.gridy = 2;
133                versionField = new JTextArea("Version x.x");
134                versionField.setEditable(false);
135                versionField.setOpaque(false);
136                Font f = new Font("Lucida Grande", Font.PLAIN, 10);
137                versionField.setFont(f);
138                c.add(versionField, gbc);
139                
140                // Credits
141                gbc.gridy = 3;
142                gbc.fill = GridBagConstraints.HORIZONTAL;
143                creditsField = new JEditorPane();
144                creditsField.setMargin(new Insets(2, 4, 2, 4));
145                creditsField.setEditable(false);
146                creditsScrollPane = new JScrollPane(creditsField,
147                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
148                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
149                Insets i;
150                Border bo = creditsScrollPane.getBorder();
151                if (bo != null)
152                        i = bo.getBorderInsets(creditsScrollPane);
153                else
154                        i = new Insets(0, 0, 0, 0);
155                creditsScrollPane.setBorder(BorderFactory.createCompoundBorder(
156                        BorderFactory.createEmptyBorder(0, -i.left + 1, 0, -i.right + 1), bo));
157                creditsScrollPane.setPreferredSize(new Dimension(100, 200));
158                c.add(creditsScrollPane, gbc);
159                
160                // Copyright
161                gbc.gridy = 4;
162                gbc.insets.bottom = 32;
163                gbc.fill = GridBagConstraints.NONE;
164                copyrightField = new JTextArea(" ");
165                copyrightField.setEditable(false);
166                copyrightField.setOpaque(false);
167                copyrightField.setFont(f);
168                c.add(copyrightField, gbc);
169                
170                // Set the initial state of the controls
171                applicationIconLabel.setVisible(false);
172                creditsScrollPane.setVisible(false);
173                if (applicationName != null)
174                        applicationNameField.setText(applicationName);
175                this.applicationVersion = applicationVersion;
176                if (applicationVersion != null)
177                        versionField.setText(applicationVersion);
178                
179                // Size and center the frame
180                packAndCenter();
181        }
182        
183        /**
184         * Set the icon of the application to be displayed.
185         * @param applicationIcon the icon of the application
186         */
187        public void setApplicationIcon(Icon applicationIcon)
188        {
189                applicationIconLabel.setIcon(applicationIcon);
190                applicationIconLabel.setVisible(applicationIcon != null);
191                packAndCenter();
192        }
193        
194        /**
195         * Set the name of the application to be displayed. If the application
196         * version is null, the string "java" will be shown.
197         * @param applicationName the name of the application
198         */
199        public void setApplicationName(String applicationName)
200        {
201                applicationNameField.setText(
202                        applicationName != null ? applicationName : "java");
203        }
204        
205        /**
206         * Set the version of the application to be displayed. If the application
207         * version is null, the string "Version x.x" will be shown.
208         * @param applicationVersion the version string of the application
209         */
210        public void setApplicationVersion(String applicationVersion)
211        {
212                this.applicationVersion = applicationVersion;
213                applyVersion();
214        }
215        
216        /**
217         * Set the version of the build to be displayed. This string appears
218         * between parentheses prepended by a "v" immediately after and on the same
219         * line as the application version. If the build version is null, the
220         * parentheses and "v" are not shown.
221         * @param buildVersion the version string of the build
222         */
223        public void setBuildVersion(String buildVersion)
224        {
225                this.buildVersion = buildVersion;
226                applyVersion();
227        }
228        
229        /**
230         * Internal method to apply the version string when either the application
231         * version or the build version change.
232         */
233        private void applyVersion()
234        {
235                StringBuilder b = new StringBuilder();
236                if (applicationVersion != null)
237                    b.append(applicationVersion);
238                else
239                        b.append("Version x.x");
240                if (buildVersion != null)
241                {
242                        b.append(" (v");
243                        b.append(buildVersion);
244                        b.append(")");
245                }
246                versionField.setText(b.toString());
247        }
248        
249        /**
250         * Set the text to be displayed in the credits area of the About frame.
251         * This area is only visible if the credits string is non-null. The content
252         * type must be one of text/plain, text/rtf, or text/html. If the type is
253         * text/html and there are hyperlinks in the text, you should register an
254         * hyperlink listener with the method <code>setHyperlinkListener()</code>.
255         * 
256         * @param credits the credits string to display
257         * @param contentType the content type of the credits string
258         * @see #setHyperlinkListener
259         */
260        public void setCredits(String credits, String contentType)
261        {
262                if (credits != null)
263                        creditsField.setContentType(contentType);
264                creditsField.setText(credits != null ? credits : "");
265                creditsField.setCaretPosition(0);
266                creditsScrollPane.setVisible(credits != null);
267                packAndCenter();
268        }
269        
270        /**
271         * Set the preferred size of the credits area of the About frame. By
272         * default, the preferred size is 100 by 150.
273         * @param preferredSize the preferred size to use
274         */
275        public void setCreditsPreferredSize(Dimension preferredSize)
276        {
277                creditsScrollPane.setPreferredSize(preferredSize);
278                packAndCenter();
279        }
280        
281        /**
282         * Set the hyperlink listener to be called when hyperlinks are clicked in
283         * the credits field. To remove it, pass <code>null</code>.
284         * @param l the hyperlink listener
285         */
286        public void setHyperlinkListener(HyperlinkListener l)
287        {
288                if (this.hyperlinkListener != null)
289                        creditsField.removeHyperlinkListener(this.hyperlinkListener);
290                this.hyperlinkListener = l;
291                if (l != null)
292                        creditsField.addHyperlinkListener(l);
293        }
294        
295        /**
296         * Set the coyright text to be displayed.
297         * @param copyright the copyright text to display
298         */
299        public void setCopyright(String copyright)
300        {
301                copyrightField.setText(copyright != null ? copyright : " ");
302                packAndCenter();
303        }
304        
305        /**
306         * Internal method to pack and center the About frame.
307         */
308        private void packAndCenter()
309        {
310                pack();
311                setSize(285, getSize().height);
312                Dimension ss = getToolkit().getScreenSize();
313                Dimension fs = getSize();
314                setLocation((ss.width - fs.width) / 2, (ss.height - fs.height) / 4);
315        }
316}