1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.xnap.gui;
21
22 import java.awt.BorderLayout;
23 import java.awt.Color;
24 import java.awt.Component;
25 import java.awt.Dimension;
26 import java.awt.Font;
27 import java.util.Hashtable;
28 import java.util.Iterator;
29
30 import javax.swing.JLabel;
31 import javax.swing.JPanel;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTabbedPane;
34 import javax.swing.JTextArea;
35 import javax.swing.border.EmptyBorder;
36 import javax.swing.event.HyperlinkEvent;
37 import javax.swing.event.HyperlinkListener;
38
39 import org.xnap.XNap;
40 import org.xnap.gui.component.DefaultDialog;
41 import org.xnap.gui.component.HTMLEditorPane;
42 import org.xnap.gui.plugin.PluginDetailsDialog;
43 import org.xnap.gui.util.GUIHelper;
44 import org.xnap.gui.util.IconHelper;
45 import org.xnap.plugin.PluginInfo;
46 import org.xnap.plugin.PluginManager;
47
48 /***
49 * XNap's About dialog. It displays XNap's about information, an authors
50 * section and XNap's license in a tabbed pane and offers an additional
51 * plugins panel.
52 *
53 * AboutDialog follows the singleton pattern.
54 */
55 public class AboutDialog extends DefaultDialog
56 {
57
58
59
60 private static AboutDialog instance = null;
61
62 private JTabbedPane jtpMain;
63 private HTMLEditorPane jepPlugins;
64
65 private Hashtable tabByFilename = new Hashtable();
66
67
68
69 private AboutDialog()
70 {
71 super(BUTTON_CLOSE);
72 initialize();
73 }
74
75
76
77 /***
78 * Sets up the tabbed pane and its panels.
79 */
80 private void initialize()
81 {
82
83 jtpMain = new JTabbedPane();
84 jtpMain.setPreferredSize(new Dimension(600, 300));
85
86
87 JPanel jpAbout = new JPanel();
88 jpAbout.setBackground(Color.white);
89 jpAbout.setLayout(new BorderLayout());
90 JLabel logoLabel = new JLabel(IconHelper.getImage("xnap_logo.png"));
91 logoLabel.setBorder(new EmptyBorder(5, 5, 5, 5));
92 jpAbout.add(logoLabel, "North");
93 JTextArea jtaAbout= new JTextArea(5, 40);
94 jtaAbout.setEditable (false);
95 jtaAbout.setBorder(new EmptyBorder(5, 5, 5, 5));
96 jpAbout.add(jtaAbout, "Center");
97 JScrollPane about = new JScrollPane(jpAbout);
98 GUIHelper.showFile(jtaAbout, "README",
99 XNap.tr("File {0} not found!", "README"));
100 jtpMain.addTab(XNap.tr("About"), about);
101
102
103 JTextArea jtaNotes = new JTextArea(15, 40);
104 jtaNotes.setBorder(new EmptyBorder(5, 5, 5, 5));
105 jtaNotes.setEditable (false);
106 JScrollPane notes = new JScrollPane(jtaNotes);
107 GUIHelper.showFile(jtaNotes, "NOTES",
108 XNap.tr("File {0} not found!", "NOTES"));
109 jtpMain.addTab(XNap.tr("Release Notes"), notes);
110
111
112 JTextArea jtaAuthors = new JTextArea(15, 40);
113 jtaAuthors.setBorder(new EmptyBorder(5, 5, 5, 5));
114 jtaAuthors.setEditable (false);
115 JScrollPane authors = new JScrollPane(jtaAuthors);
116 GUIHelper.showFile(jtaAuthors, "AUTHORS",
117 XNap.tr("File {0} not found!", "AUTHORS"));
118 jtpMain.addTab(XNap.tr("Authors"), authors);
119
120
121 getTab("License Agreement", "COPYING",
122 XNap.tr("File COPYING not found!\nSee http://xnap.sf.net/license.html instead."));
123
124
125 jepPlugins = new HTMLEditorPane(false);
126 jepPlugins.addHyperlinkListener(new LicenseLinkListener());
127 jepPlugins.setBorder(new EmptyBorder(5, 5, 5, 5));
128 JScrollPane plugins = new JScrollPane(jepPlugins);
129 jtpMain.addTab(XNap.tr("Plugins"), plugins);
130
131 setTitle(XNap.tr("About XNap", 0, 1) + PluginManager.getCoreVersion());
132 setMainComponent(jtpMain);
133 pack();
134 }
135
136 /***
137 * Adds a new license tab.
138 *
139 * License files are supposed to be pure text files.
140 *
141 * @param name of the license
142 * @param filename filename of the license text to load
143 * @param fallbackText this text is shown when the file couldn't be loaded
144 */
145 public synchronized Component getTab(String name, String filename,
146 String fallbackText)
147 {
148 Component c = (Component)tabByFilename.get(filename);
149 if (c == null) {
150 if (filename.endsWith("html")) {
151 HTMLEditorPane jta = new HTMLEditorPane();
152 jta.setBorder(new EmptyBorder(5, 5, 5, 5));
153 GUIHelper.showFile(jta, filename, fallbackText);
154 c = new JScrollPane(jta);
155 }
156 else {
157 JTextArea jta = new JTextArea(15, 40);
158 jta.setBorder(new EmptyBorder(5, 5, 5, 5));
159 jta.setEditable (false);
160 jta.setFont(new Font("Monospaced", Font.PLAIN, 12));
161 GUIHelper.showFile(jta, filename, fallbackText);
162 c = new JScrollPane(jta);
163 }
164 jtpMain.addTab(name, c);
165
166 tabByFilename.put(filename, c);
167 }
168
169 return c;
170 }
171
172 public void dispose()
173 {
174 super.dispose();
175 instance = null;
176 }
177
178 /***
179 * Sets this dialogs position relative to <code>c</code> and makes it
180 * visible.
181 */
182 public static void showDialog(Component c, String tab)
183 {
184 if (instance == null) {
185 instance = new AboutDialog();
186 if (c != null) {
187 instance.setLocationRelativeTo(c);
188 }
189 }
190
191 instance.updatePluginsPanel();
192 if (tab != null) {
193 Component comp = instance.getTab(tab, tab, XNap.tr("{0} not found!",
194 tab));
195 instance.jtpMain.setSelectedComponent(comp);
196 }
197 instance.show(c);
198 }
199
200 public static void showDialog(Component c)
201 {
202 showDialog(c, null);
203 }
204
205 private void updatePluginsPanel()
206 {
207 StringBuffer content = new StringBuffer();
208 Iterator i = PluginManager.getInstance().infos();
209
210 HTMLEditorPane.addHeader(content);
211
212 while (i.hasNext()) {
213 PluginInfo info = (PluginInfo)i.next();
214 if (!info.isEnabled()) {
215 continue;
216 }
217
218 PluginDetailsDialog.addPluginInfo(content, info);
219 }
220
221 HTMLEditorPane.addFooter(content);
222
223 jepPlugins.setText(content.toString());
224 jepPlugins.setCaretPosition(0);
225 }
226
227 /***
228 * Listens for hyperlink events and switches the panels of the tabbed pain
229 * when the link description matches a license displayed in one of the
230 * panels.
231 */
232 private class LicenseLinkListener implements HyperlinkListener
233 {
234 public void hyperlinkUpdate(HyperlinkEvent e)
235 {
236 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED
237 && e.getDescription() != null) {
238 Component c
239 = getTab(e.getDescription(), e.getDescription(),
240 XNap.tr("File {0} not found!",
241 e.getDescription()));
242 jtpMain.setSelectedComponent(c);
243 }
244 }
245 }
246
247 }