1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.diyefi.openlogviewer.subframes;
24
25 import java.awt.BorderLayout;
26 import java.awt.Component;
27 import java.awt.Dimension;
28 import java.awt.Font;
29 import java.awt.Insets;
30 import java.io.IOException;
31 import java.text.DateFormat;
32 import java.text.SimpleDateFormat;
33 import java.util.Date;
34 import java.util.Locale;
35 import java.util.Properties;
36
37 import javax.swing.BorderFactory;
38 import javax.swing.Box;
39 import javax.swing.BoxLayout;
40 import javax.swing.ImageIcon;
41 import javax.swing.JEditorPane;
42 import javax.swing.JFrame;
43 import javax.swing.JLabel;
44 import javax.swing.JPanel;
45 import javax.swing.JTextPane;
46 import javax.swing.UIManager;
47 import javax.swing.event.HyperlinkEvent;
48 import javax.swing.event.HyperlinkListener;
49 import javax.swing.text.SimpleAttributeSet;
50 import javax.swing.text.StyleConstants;
51
52 import org.diyefi.openlogviewer.OpenLogViewer;
53 import org.diyefi.openlogviewer.utils.MathUtils;
54
55 public final class AboutFrame extends JFrame {
56 private static final double bytesPerMegaByte = 1048576;
57 private static final long serialVersionUID = 1L;
58 private static final int FRAME_WIDTH = 450;
59 private static final int SPACER_HEIGHT = 20;
60 private static final String LINK_CLOSE = "</a>";
61
62 private final Properties buildInfo;
63
64 private static final HyperlinkListener HLL = new HyperlinkListener() {
65 public void hyperlinkUpdate(final HyperlinkEvent hle) {
66 if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
67 try {
68 java.awt.Desktop.getDesktop().browse(java.net.URI.create(hle.getDescription()));
69 } catch (IOException e) {
70 OpenLogViewer.getInstance().defaultBrowserNotFound();
71 }
72 }
73 }
74 };
75
76 private static AboutFrame aboutFrame;
77
78
79
80
81
82
83
84 public static void show(final Properties buildInfo) {
85 synchronized(HLL) {
86 if (aboutFrame != null) {
87 aboutFrame.setVisible(true);
88 } else {
89 aboutFrame = new AboutFrame(buildInfo);
90 }
91 }
92 }
93
94 private AboutFrame(final Properties buildInfo) {
95 setDefaultCloseOperation(DISPOSE_ON_CLOSE);
96
97 this.buildInfo = buildInfo;
98 final BorderLayout lm = new BorderLayout();
99 lm.setHgap(SPACER_HEIGHT);
100 setLayout(lm);
101
102 OpenLogViewer.setupWindowKeyBindings(this);
103
104 final JPanel north = createNorthPanel();
105 final JPanel center = createCenterPanel();
106 final JPanel south = createSouthPanel();
107 add(north, BorderLayout.NORTH);
108 add(center, BorderLayout.CENTER);
109 add(south, BorderLayout.SOUTH);
110
111 setTitle("About - " + buildInfo.getProperty("application.title"));
112
113 pack();
114
115 final Insets insets = getInsets();
116 final int width = FRAME_WIDTH + insets.left + insets.right;
117 setPreferredSize(new Dimension(width, 0));
118
119 final int height = north.getHeight() + center.getHeight() + south.getHeight() + insets.top + insets.bottom;
120 setMinimumSize(new Dimension(width, height));
121 setPreferredSize(new Dimension(width, height));
122
123 pack();
124
125 setVisible(true);
126 }
127
128 private JPanel createNorthPanel() {
129 final String appName = OpenLogViewer.class.getSimpleName();
130 final JPanel northPanel = new JPanel();
131 northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS));
132
133 final ImageIcon icon = createImageIcon("logo64x64.png", appName + " Logo");
134 final JLabel logo = new JLabel(icon);
135 logo.setAlignmentX(Component.CENTER_ALIGNMENT);
136 northPanel.add(logo);
137
138 addTextToPanel(northPanel, appName);
139 addTextToPanel(northPanel, "Version: " + buildInfo.getProperty("project.version"));
140 addTextToPanel(northPanel, "Detailed version: " + buildInfo.getProperty("git.commit.id.describe"));
141 addTextToPanel(northPanel, "Git SHA1 hash: " + buildInfo.getProperty("git.commit.id"));
142
143 return northPanel;
144 }
145
146 private JPanel createCenterPanel() {
147 final JPanel centerPanel = new JPanel();
148 centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
149
150 final JTextPane description = new JTextPane();
151 final SimpleAttributeSet simpleAttrib = new SimpleAttributeSet();
152 StyleConstants.setAlignment(simpleAttrib, StyleConstants.ALIGN_JUSTIFIED);
153 description.setParagraphAttributes(simpleAttrib, false);
154
155 description.setText(buildInfo.getProperty("project.description"));
156 description.setEditable(false);
157 description.setOpaque(false);
158 description.setBorder(BorderFactory.createEmptyBorder(SPACER_HEIGHT, SPACER_HEIGHT, SPACER_HEIGHT, SPACER_HEIGHT));
159 description.setAlignmentX(Component.CENTER_ALIGNMENT);
160 description.setSize(new Dimension(FRAME_WIDTH, Integer.MAX_VALUE));
161 centerPanel.add(description);
162
163 final String website = buildInfo.getProperty("project.url");
164 final String forumUrl = buildInfo.getProperty("project.forum.url");
165 final String issuesUrl = buildInfo.getProperty("project.issueManagement.url");
166 addTextToPanel(centerPanel, "Website: <a href='" + website + "'>" + website + LINK_CLOSE);
167 addTextToPanel(centerPanel, "Issues: <a href='" + issuesUrl + "'>" + issuesUrl + LINK_CLOSE);
168 addTextToPanel(centerPanel, "Support: <a href='" + forumUrl + "'>" + forumUrl + LINK_CLOSE);
169
170 addTextToPanel(centerPanel, "Licensed under the <a href='http://www.gnu.org/licenses/quick-guide-gplv3.html'>GNU General Public License (GPL) V3</a>");
171
172 centerPanel.add(Box.createVerticalStrut(SPACER_HEIGHT));
173
174 return centerPanel;
175 }
176
177 private JPanel createSouthPanel() {
178 final JPanel southPanel = new JPanel();
179 southPanel.setLayout(new BoxLayout(southPanel, BoxLayout.Y_AXIS));
180
181 addTextToPanel(southPanel, "Built by " + buildInfo.getProperty("git.build.user.name") + " using <a href='http://maven.apache.org/'>Maven " + buildInfo.getProperty("maven.version") + LINK_CLOSE);
182 addTextToPanel(southPanel, "Built on " + buildInfo.getProperty("os.name") + " " + buildInfo.getProperty("os.arch") + " " + buildInfo.getProperty("os.version"));
183 addTextToPanel(southPanel, "Built using Java " + buildInfo.getProperty("java.version") + " on a " + buildInfo.getProperty("java.vm.version") + " VM");
184 addTextToPanel(southPanel, "Build date and time: " + buildInfo.getProperty("git.build.time"));
185
186 southPanel.add(Box.createVerticalStrut(SPACER_HEIGHT));
187
188 final Properties sys = System.getProperties();
189 addTextToPanel(southPanel, "Running on " + sys.getProperty("os.name") + " " + sys.getProperty("os.arch") + " " + sys.getProperty("os.version"));
190 addTextToPanel(southPanel, "Running using Java " + sys.getProperty("java.version") + " on a " + sys.getProperty("java.vm.version") + " VM");
191 final DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy @ HH:mm:ss z", Locale.ENGLISH);
192 addTextToPanel(southPanel, "Current date and time: " + dateFormat.format(new Date()));
193
194 southPanel.add(Box.createVerticalStrut(SPACER_HEIGHT));
195
196 final Runtime ourRuntime = Runtime.getRuntime();
197 final double limitMax = ourRuntime.maxMemory() / bytesPerMegaByte;
198 final double currentMax = ourRuntime.totalMemory() / bytesPerMegaByte;
199 final double currentFree = ourRuntime.freeMemory() / bytesPerMegaByte;
200 final double futureFree = limitMax - currentMax;
201 final double limitFree = currentFree + futureFree;
202 final double used = currentMax - currentFree;
203
204 addTextToPanel(southPanel, "Memory usage details: "
205 + "Used: "
206 + MathUtils.roundDecimalPlaces(used, 2)
207 + "MB");
208 addTextToPanel(southPanel, "Current free/max: "
209 + MathUtils.roundDecimalPlaces(currentFree, 2)
210 + "MB/"
211 + MathUtils.roundDecimalPlaces(currentMax, 2)
212 + "MB");
213 addTextToPanel(southPanel, "Hard limit free/max: "
214 + MathUtils.roundDecimalPlaces(limitFree, 2)
215 + "MB/"
216 + MathUtils.roundDecimalPlaces(limitMax, 2)
217 + "MB");
218
219 return southPanel;
220 }
221
222 private void addTextToPanel(final JPanel panel, final String text) {
223 final Font font = UIManager.getFont("Label.font");
224 final StringBuilder bodyRule = new StringBuilder("body { font-family: ");
225 bodyRule.append(font.getFamily());
226 bodyRule.append("; font-size: ");
227 bodyRule.append(font.getSize());
228 bodyRule.append("pt; text-align: center;}");
229 final JEditorPane newPane = new JEditorPane("text/html", text);
230 ((javax.swing.text.html.HTMLDocument) newPane.getDocument()).getStyleSheet().addRule(bodyRule.toString());
231 newPane.addHyperlinkListener(HLL);
232 newPane.setEditable(false);
233 newPane.setBorder(null);
234 newPane.setOpaque(false);
235 newPane.setAlignmentX(Component.CENTER_ALIGNMENT);
236
237 panel.add(newPane);
238 }
239
240 private ImageIcon createImageIcon(final String path, final String description) {
241 final java.net.URL imgURL = OpenLogViewer.class.getResource(path);
242 if (imgURL != null) {
243 return new ImageIcon(imgURL, description);
244 } else {
245 System.err.println("Couldn't find file: " + path);
246 return null;
247 }
248 }
249
250
251 @Override
252 public void dispose() {
253 synchronized (HLL) {
254 aboutFrame = null;
255 super.dispose();
256 }
257 }
258 }