cc337b2e027fa38780a5d3547f512902440a2097
[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         /** The tabbed pane with all the pages. */
85         private JTabbedPane pagesPane;
86
87         /**
88          * Creates a new “about” dialog.
89          * 
90          * @param swingInterface
91          *            The Swing interface
92          */
93         public AboutDialog(SwingInterface swingInterface) {
94                 super(swingInterface.getMainWindow(), I18n.get("aboutDialog.title"));
95                 initActions();
96                 initComponents();
97                 pack();
98                 SwingUtils.center(this);
99                 I18n.registerI18nable(this);
100         }
101
102         //
103         // PRIVATE METHODS
104         //
105
106         /**
107          * Initializes all actions.
108          */
109         private void initActions() {
110                 okayAction = new I18nAction("general.button.okay") {
111
112                         /**
113                          * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
114                          */
115                         @SuppressWarnings("synthetic-access")
116                         public void actionPerformed(ActionEvent e) {
117                                 actionOkay();
118                         }
119                 };
120         }
121
122         /**
123          * Initiliazes all components of the dialog.
124          */
125         private void initComponents() {
126                 JPanel contentPane = new JPanel(new BorderLayout(12, 12));
127                 getContentPane().add(contentPane, BorderLayout.CENTER);
128                 contentPane.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
129
130                 pagesPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
131                 contentPane.add(pagesPane, BorderLayout.CENTER);
132
133                 pagesPane.addTab(I18n.get("aboutDialog.page.about.title"), createAboutPage());
134                 pagesPane.setToolTipTextAt(0, I18n.get("aboutDialog.page.about.shortDescription"));
135                 pagesPane.addTab(I18n.get("aboutDialog.page.license.title"), createLicensePage());
136                 pagesPane.setToolTipTextAt(1, I18n.get("aboutDialog.page.license.shortDescription"));
137
138                 JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
139                 contentPane.add(buttonPanel, BorderLayout.PAGE_END);
140                 buttonPanel.add(new JButton(okayAction));
141         }
142
143         /**
144          * Creates the “about” page.
145          * 
146          * @return The “about” page
147          */
148         private JComponent createAboutPage() {
149                 JPanel aboutPanel = new JPanel(new BorderLayout(12, 12));
150                 aboutPanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
151
152                 /* the about page consists of an image to the left and text to right. */
153                 JComponent textPanel = new Box(BoxLayout.PAGE_AXIS);
154                 aboutPanel.add(textPanel, BorderLayout.CENTER);
155
156                 JLabel jSiteHeaderLabel = new JLabel("jSite " + Version.getVersion());
157                 textPanel.add(jSiteHeaderLabel);
158                 textPanel.add(Box.createVerticalStrut(24));
159                 Font jSiteHeaderLabelFont = jSiteHeaderLabel.getFont();
160                 jSiteHeaderLabel.setFont(jSiteHeaderLabelFont.deriveFont(jSiteHeaderLabelFont.getSize2D() * 2).deriveFont(Font.BOLD));
161
162                 contributorsLabel = new I18nLabel("aboutDialog.page.about.label.contributor");
163                 textPanel.add(contributorsLabel);
164                 textPanel.add(Box.createVerticalStrut(12));
165                 contributorsLabel.setFont(contributorsLabel.getFont().deriveFont(Font.BOLD));
166
167                 for (Contributor contributor: CONTRIBUTORS) {
168                         JLabel contributorLabel = new JLabel(contributor.getName() + " <" + contributor.getEmail() + "> (" + contributor.getPart() + ")");
169                         textPanel.add(contributorLabel);
170                 }
171                 textPanel.add(Box.createVerticalStrut(24));
172
173                 i18nMaintainerLabel = new I18nLabel("aboutDialog.page.about.label.i18nMaintainer");
174                 textPanel.add(i18nMaintainerLabel);
175                 textPanel.add(Box.createVerticalStrut(12));
176                 i18nMaintainerLabel.setFont(i18nMaintainerLabel.getFont().deriveFont(Font.BOLD));
177
178                 i18nMaintainerNameLabel = new JLabel(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
179                 textPanel.add(i18nMaintainerNameLabel);
180
181                 return aboutPanel;
182         }
183
184         /**
185          * Creates the “license” page.
186          * 
187          * @return The “license” page
188          */
189         private JComponent createLicensePage() {
190                 JPanel licensePanel = new JPanel(new BorderLayout(12, 12));
191                 licensePanel.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
192
193                 JPanel licenseHeaderPanel = new JPanel(new FlowLayout());
194                 licensePanel.add(licenseHeaderPanel, BorderLayout.PAGE_START);
195
196                 licenseHeaderLabel = new I18nLabel("aboutDialog.page.license.header", Version.getVersion());
197                 licenseHeaderPanel.add(licenseHeaderLabel);
198                 licenseHeaderLabel.setAlignmentX(0.5f);
199
200                 String licenseText = loadLicenseText();
201                 JTextArea licenseArea = new JTextArea(licenseText, 25, 80);
202                 licensePanel.add(new JScrollPane(licenseArea), BorderLayout.CENTER);
203                 licenseArea.setFont(new Font("Courier", Font.PLAIN, licenseArea.getFont().getSize()));
204                 licenseArea.setEditable(false);
205
206                 return licensePanel;
207         }
208
209         /**
210          * Loads the license text.
211          * 
212          * @return The license text
213          */
214         private String loadLicenseText() {
215                 InputStream licenseInputStream = getClass().getResourceAsStream("/LICENSE");
216                 if (licenseInputStream == null) {
217                         return "Could not load LICENSE, check your installation.";
218                 }
219                 ByteArrayOutputStream licenseOutputStream = new ByteArrayOutputStream(20000);
220                 try {
221                         StreamCopier.copy(licenseInputStream, licenseOutputStream);
222                 } catch (IOException e) {
223                         return "Could not load LICENSE, check your installation.";
224                 }
225                 String licenseText;
226                 try {
227                         licenseText = new String(licenseOutputStream.toByteArray(), "ISO-8859-1");
228                 } catch (UnsupportedEncodingException e) {
229                         licenseText = new String(licenseOutputStream.toByteArray());
230                 }
231                 return licenseText;
232         }
233
234         //
235         // PRIVATE ACTIONS
236         //
237
238         /**
239          * Closes the dialog.
240          */
241         private void actionOkay() {
242                 setVisible(false);
243         }
244
245         //
246         // INTERFACE I18nable
247         //
248
249         /**
250          * @see net.pterodactylus.jsite.i18n.I18nable#updateI18n()
251          */
252         public void updateI18n() {
253                 contributorsLabel.updateI18n();
254                 licenseHeaderLabel.updateI18n();
255                 i18nMaintainerLabel.updateI18n();
256                 i18nMaintainerNameLabel.setText(I18n.get("i18n.maintainer.name") + " <" + I18n.get("i18n.maintainer.email") + ">");
257                 okayAction.updateI18n();
258                 setTitle(I18n.get("aboutDialog.title"));
259                 pagesPane.setTitleAt(0, I18n.get("aboutDialog.page.about.title"));
260                 pagesPane.setToolTipTextAt(0, I18n.get("aboutDialog.page.about.shortDescription"));
261                 pagesPane.setTitleAt(1, I18n.get("aboutDialog.page.license.title"));
262                 pagesPane.setToolTipTextAt(1, I18n.get("aboutDialog.page.license.shortDescription"));
263                 SwingUtils.repackCentered(this);
264         }
265
266         /**
267          * Container for a contributor.
268          * 
269          * @author David ‘Bombe’ Roden &lt;bombe@freenetproject.org&gt;
270          * @version $Id$
271          */
272         private static class Contributor {
273
274                 /** The name of the contributor. */
275                 private final String name;
276
277                 /** The email address of the contributor. */
278                 private final String email;
279
280                 /** The parts where the contributor helped. */
281                 private final String part;
282
283                 /**
284                  * Creates a new contributor.
285                  * 
286                  * @param name
287                  *            The name of the contributor
288                  * @param email
289                  *            The email address of the contributor
290                  * @param part
291                  *            The parts where the contributor helped
292                  */
293                 public Contributor(String name, String email, String part) {
294                         this.name = name;
295                         this.email = email;
296                         this.part = part;
297                 }
298
299                 /**
300                  * Returns the name of the contributor.
301                  * 
302                  * @return The name of the contributor
303                  */
304                 String getName() {
305                         return name;
306                 }
307
308                 /**
309                  * Returns the email address of the contributor.
310                  * 
311                  * @return The email address of the contributor
312                  */
313                 String getEmail() {
314                         return email;
315                 }
316
317                 /**
318                  * Returns the parts where the contributor helped.
319                  * 
320                  * @return The parts where the contributor helped
321                  */
322                 String getPart() {
323                         return part;
324                 }
325
326         }
327
328 }