complete about dialog
[jSite2.git] / src / net / pterodactylus / jsite / gui / AboutDialog.java
1 /*
2  * jSite2 - AboutDialog.java -
3  * Copyright © 2008 David Roden
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 package net.pterodactylus.jsite.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.FlowLayout;
24 import java.awt.Font;
25 import java.awt.event.ActionEvent;
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.UnsupportedEncodingException;
30 import java.util.ArrayList;
31 import java.util.List;
32
33 import javax.swing.BorderFactory;
34 import javax.swing.Box;
35 import javax.swing.BoxLayout;
36 import javax.swing.JButton;
37 import javax.swing.JComponent;
38 import javax.swing.JDialog;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTabbedPane;
43 import javax.swing.JTextArea;
44 import javax.swing.SwingConstants;
45
46 import net.pterodactylus.jsite.i18n.I18n;
47 import net.pterodactylus.jsite.i18n.I18nable;
48 import net.pterodactylus.jsite.i18n.gui.I18nAction;
49 import net.pterodactylus.jsite.i18n.gui.I18nLabel;
50 import net.pterodactylus.jsite.main.Version;
51 import net.pterodactylus.util.io.StreamCopier;
52 import net.pterodactylus.util.swing.SwingUtils;
53
54 /**
55  * An “about” dialog.
56  * 
57  * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
58  * @version $Id$
59  */
60 public class AboutDialog extends JDialog implements I18nable {
61
62         /** A list of all contributors. */
63         private static final List<Contributor> CONTRIBUTORS = new ArrayList<Contributor>();
64
65         static {
66                 CONTRIBUTORS.add(new Contributor("David ‘Bombe’ Roden", "bombe@freenetproject.org", "Main code"));
67         }
68
69         /** The “okay” button action. */
70         private I18nAction okayAction;
71
72         /** The contributors label. */
73         private I18nLabel contributorsLabel;
74
75         /** The i18n maintainer label. */
76         private I18nLabel i18nMaintainerLabel;
77
78         /** The i18n maintainer’s name label. */
79         private JLabel i18nMaintainerNameLabel;
80
81         /** The license header. */
82         private I18nLabel licenseHeaderLabel;
83
84         /**
85          * Creates a new “about” dialog.
86          * 
87          * @param swingInterface
88          *            The Swing interface
89          */
90         public AboutDialog(SwingInterface swingInterface) {
91                 super(swingInterface.getMainWindow(), I18n.get("aboutDialog.title"));
92                 initActions();
93                 initComponents();
94                 pack();
95                 SwingUtils.center(this);
96                 I18n.registerI18nable(this);
97         }
98
99         //
100         // PRIVATE METHODS
101         //
102
103         /**
104          * Initializes all actions.
105          */
106         private void initActions() {
107                 okayAction = new I18nAction("general.button.okay") {
108                         /**
109                          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
110                          */
111                         @SuppressWarnings("synthetic-access")
112                         public void actionPerformed(ActionEvent e) {
113                                 actionOkay();
114                         }
115                 };
116         }
117
118         /**
119          * Initiliazes all components of the dialog.
120          */
121         private void initComponents() {
122                 JPanel contentPane = new JPanel(new BorderLayout(12, 12));
123                 getContentPane().add(contentPane, BorderLayout.CENTER);
124                 contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
125
126                 JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
127                 contentPane.add(tabbedPane, BorderLayout.CENTER);
128
129                 tabbedPane.addTab(I18n.get("aboutDialog.page.about.title"), createAboutPage());
130                 tabbedPane.setToolTipTextAt(0, I18n.get("aboutDialog.page.about.shortDescription"));
131                 tabbedPane.addTab(I18n.get("aboutDialog.page.license.title"), createLicensePage());
132                 tabbedPane.setToolTipTextAt(1, I18n.get("aboutDialog.page.license.shortDescription"));
133
134                 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
135                 contentPane.add(buttonPanel, BorderLayout.PAGE_END);
136                 buttonPanel.add(new JButton(okayAction));
137         }
138
139         /**
140          * Creates the “about” page.
141          * 
142          * @return The “about” page
143          */
144         private JComponent createAboutPage() {
145                 JPanel aboutPanel = new JPanel(new BorderLayout(12, 12));
146                 aboutPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
147
148                 /* the about page consists of an image to the left and text to right. */
149                 JComponent textPanel = new Box(BoxLayout.PAGE_AXIS);
150                 aboutPanel.add(textPanel, BorderLayout.CENTER);
151
152                 JLabel jSiteHeaderLabel = new JLabel("jSite " + Version.getVersion());
153                 textPanel.add(jSiteHeaderLabel);
154                 textPanel.add(Box.createVerticalStrut(24));
155                 Font jSiteHeaderLabelFont = jSiteHeaderLabel.getFont();
156                 jSiteHeaderLabel.setFont(jSiteHeaderLabelFont.deriveFont(jSiteHeaderLabelFont.getSize2D() * 2).deriveFont(Font.BOLD));
157
158                 contributorsLabel = new I18nLabel("aboutDialog.page.about.label.contributor");
159                 textPanel.add(contributorsLabel);
160                 textPanel.add(Box.createVerticalStrut(12));
161                 contributorsLabel.setFont(contributorsLabel.getFont().deriveFont(Font.BOLD));
162
163                 for (Contributor contributor: CONTRIBUTORS) {
164                         JLabel contributorLabel = new JLabel(contributor.getName() + " <" + contributor.getEmail() + "> (" + contributor.getPart() + ")");
165                         textPanel.add(contributorLabel);
166                 }
167                 textPanel.add(Box.createVerticalStrut(24));
168
169                 i18nMaintainerLabel = new I18nLabel("aboutDialog.page.about.label.i18nMaintainer");
170                 textPanel.add(i18nMaintainerLabel);
171                 textPanel.add(Box.createVerticalStrut(12));
172                 i18nMaintainerLabel.setFont(i18nMaintainerLabel.getFont().deriveFont(Font.BOLD));
173
174                 i18nMaintainerNameLabel = new JLabel(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
175                 textPanel.add(i18nMaintainerNameLabel);
176
177                 return aboutPanel;
178         }
179
180         /**
181          * Creates the “license” page.
182          * 
183          * @return The “license” page
184          */
185         private JComponent createLicensePage() {
186                 JPanel licensePanel = new JPanel(new BorderLayout(12, 12));
187                 licensePanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
188
189                 licenseHeaderLabel = new I18nLabel("aboutDialog.page.license.header", Version.getVersion());
190                 licensePanel.add(licenseHeaderLabel, BorderLayout.PAGE_START);
191                 licenseHeaderLabel.setAlignmentX(0.5f);
192
193                 String licenseText = loadLicenseText();
194                 JTextArea licenseArea = new JTextArea(licenseText, 25, 80);
195                 licensePanel.add(new JScrollPane(licenseArea), BorderLayout.CENTER);
196                 licenseArea.setFont(new Font("Courier", Font.PLAIN, licenseArea.getFont().getSize()));
197                 licenseArea.setEditable(false);
198
199                 return licensePanel;
200         }
201
202         /**
203          * Loads the license text.
204          * 
205          * @return The license text
206          */
207         private String loadLicenseText() {
208                 InputStream licenseInputStream = getClass().getResourceAsStream("/LICENSE");
209                 if (licenseInputStream == null) {
210                         return "Could not load LICENSE, check your installation.";
211                 }
212                 ByteArrayOutputStream licenseOutputStream = new ByteArrayOutputStream(20000);
213                 try {
214                         StreamCopier.copy(licenseInputStream, licenseOutputStream);
215                 } catch (IOException e) {
216                         return "Could not load LICENSE, check your installation.";
217                 }
218                 String licenseText;
219                 try {
220                         licenseText = new String(licenseOutputStream.toByteArray(), "ISO-8859-1");
221                 } catch (UnsupportedEncodingException e) {
222                         licenseText = new String(licenseOutputStream.toByteArray());
223                 }
224                 return licenseText;
225         }
226
227         //
228         // PRIVATE ACTIONS
229         //
230
231         /**
232          * Closes the dialog.
233          */
234         private void actionOkay() {
235                 setVisible(false);
236         }
237
238         //
239         // INTERFACE I18nable
240         //
241
242         /**
243          * @see net.pterodactylus.jsite.i18n.I18nable#updateI18n()
244          */
245         public void updateI18n() {
246                 contributorsLabel.updateI18n();
247                 licenseHeaderLabel.updateI18n();
248                 i18nMaintainerLabel.updateI18n();
249                 i18nMaintainerNameLabel.setText(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
250                 okayAction.updateI18n();
251                 setTitle(I18n.get("aboutDialog.title"));
252                 SwingUtils.repackCentered(this);
253         }
254
255         /**
256          * Container for a contributor.
257          * 
258          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
259          * @version $Id$
260          */
261         private static class Contributor {
262
263                 /** The name of the contributor. */
264                 private final String name;
265
266                 /** The email address of the contributor. */
267                 private final String email;
268
269                 /** The parts where the contributor helped. */
270                 private final String part;
271
272                 /**
273                  * Creates a new contributor.
274                  * 
275                  * @param name
276                  *            The name of the contributor
277                  * @param email
278                  *            The email address of the contributor
279                  * @param part
280                  *            The parts where the contributor helped
281                  */
282                 public Contributor(String name, String email, String part) {
283                         this.name = name;
284                         this.email = email;
285                         this.part = part;
286                 }
287
288                 /**
289                  * Returns the name of the contributor.
290                  * 
291                  * @return The name of the contributor
292                  */
293                 String getName() {
294                         return name;
295                 }
296
297                 /**
298                  * Returns the email address of the contributor.
299                  * 
300                  * @return The email address of the contributor
301                  */
302                 String getEmail() {
303                         return email;
304                 }
305
306                 /**
307                  * Returns the parts where the contributor helped.
308                  * 
309                  * @return The parts where the contributor helped
310                  */
311                 String getPart() {
312                         return part;
313                 }
314
315         }
316
317 }