View Javadoc

1   /*
2    *  XNap - A P2P framework and client.
3    *
4    *  See the file AUTHORS for copyright information.
5    *
6    *  This program is free software; you can redistribute it and/or modify
7    *  it under the terms of the GNU General Public License as published by
8    *  the Free Software Foundation.
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 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      //--- Data field(s) ---
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      //--- Constructor(s) ---
68  
69      private AboutDialog()
70      {
71  		super(BUTTON_CLOSE);
72  		initialize();
73      }
74  
75      // --- Methods ---
76  
77      /***
78       * Sets up the tabbed pane and its panels.
79       */
80      private void initialize()
81      {
82  		// tabbed pane
83  		jtpMain = new JTabbedPane();
84          jtpMain.setPreferredSize(new Dimension(600, 300));
85  		
86  		// about tab
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 		// notes tab
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 		// authors tab
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 		// license tab
121 		getTab("License Agreement", "COPYING",
122 			   XNap.tr("File COPYING not found!\nSee http://xnap.sf.net/license.html instead."));
123 
124 		// plugins tab
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 }