1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.ui;
39
40 import java.awt.BorderLayout;
41 import java.awt.FlowLayout;
42 import java.awt.Font;
43 import java.awt.Insets;
44 import java.awt.event.ActionEvent;
45 import java.awt.event.ActionListener;
46 import java.io.*;
47 import java.util.Hashtable;
48 import java.util.Vector;
49 import java.util.logging.Logger;
50 import javax.swing.BorderFactory;
51 import javax.swing.ImageIcon;
52 import javax.swing.JButton;
53 import javax.swing.JFileChooser;
54 import javax.swing.JLabel;
55 import javax.swing.JPanel;
56 import javax.swing.JProgressBar;
57 import javax.swing.JScrollPane;
58 import javax.swing.JTabbedPane;
59 import javax.swing.JTextArea;
60 import javax.swing.JToolBar;
61 import javax.swing.border.Border;
62 import javax.swing.border.EtchedBorder;
63
64
65
66
67
68
69
70 public class LogPanel extends JPanel implements ActionListener {
71
72 @Serial
73 private static final long serialVersionUID = 1L;
74
75 private static final Logger logger = Logger.getLogger(LogPanel.class.getName());
76 private Vector<Thread> tinkerThreads;
77
78
79 private Hashtable<String, JTextArea> logFiles = new Hashtable<String, JTextArea>();
80
81 private JToolBar toolBar;
82 private JTabbedPane resultsTabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);
83 private JProgressBar statusProgressBar;
84 private Font font;
85 private JPanel noLogsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 5));
86 private EtchedBorder eb = new EtchedBorder(EtchedBorder.RAISED);
87
88
89
90
91
92
93 public LogPanel(MainPanel f) {
94 tinkerThreads = null;
95 initToolBar();
96 setLayout(new BorderLayout());
97 Border eb = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
98 statusProgressBar = new JProgressBar();
99 statusProgressBar.setBorder(eb);
100 statusProgressBar.setStringPainted(true);
101 ClassLoader loader = getClass().getClassLoader();
102 ImageIcon icon = new ImageIcon(loader.getResource("ffx/ui/icons/page_code.png"));
103 JLabel noLogsLabel = new JLabel("TINKER logs are displayed here.");
104 noLogsLabel.setIcon(icon);
105 noLogsPanel.add(noLogsLabel);
106 noLogsPanel.setBorder(eb);
107 JLabel status = new JLabel(" ");
108 status.setBorder(eb);
109 add(toolBar, BorderLayout.NORTH);
110 add(noLogsPanel, BorderLayout.CENTER);
111 add(status, BorderLayout.SOUTH);
112 font = Font.decode("Monospaced");
113 refreshStatus();
114 }
115
116
117 @Override
118 public void actionPerformed(ActionEvent evt) {
119 if (evt.getSource() instanceof javax.swing.Timer) {
120 if (resultsTabbedPane.getTabCount() > 0) {
121 refresh();
122 }
123 return;
124 }
125 String arg = evt.getActionCommand();
126 if (arg == null) {
127 return;
128 }
129 if (arg.equalsIgnoreCase("Refresh")) {
130 refresh();
131 } else if (arg.equalsIgnoreCase("Close")) {
132 close();
133 } else if (arg.equalsIgnoreCase("Close All")) {
134 closeAll();
135 } else if (arg.equalsIgnoreCase("Open...")) {
136 JFileChooser d = MainPanel.resetFileChooser();
137 d.setAcceptAllFileFilterUsed(true);
138 d.setDialogTitle("Open Log File");
139 int result = d.showOpenDialog(this);
140 if (result == JFileChooser.APPROVE_OPTION) {
141 File f = d.getSelectedFile();
142 addPane(f);
143 }
144 } else if (arg.equalsIgnoreCase("Save")) {
145 saveSelected();
146 } else if (arg.equalsIgnoreCase("Save As...")) {
147 saveSelectedAs();
148 }
149 }
150
151
152 public void close() {
153 int index = resultsTabbedPane.getSelectedIndex();
154 if (index >= 0) {
155 String title = resultsTabbedPane.getTitleAt(index);
156 resultsTabbedPane.remove(index);
157 logFiles.remove(title);
158 for (Thread t : tinkerThreads) {
159 String name = t.getName();
160 if (name.equals(title)) {
161 tinkerThreads.remove(t);
162 break;
163 }
164 }
165 if (resultsTabbedPane.getComponentCount() == 0) {
166 remove(resultsTabbedPane);
167 add(noLogsPanel, BorderLayout.CENTER);
168 }
169 validate();
170 repaint();
171 }
172 }
173
174
175
176
177
178
179 public void close(String file) {
180 synchronized (this) {
181 int index = -1;
182 for (int i = 0; i < resultsTabbedPane.getTabCount(); i++) {
183 String title = resultsTabbedPane.getTitleAt(i);
184 if (file.equals(title)) {
185 index = i;
186 break;
187 }
188 }
189 if (index < 0) {
190 return;
191 }
192 String title = resultsTabbedPane.getTitleAt(index);
193 resultsTabbedPane.remove(index);
194 logFiles.remove(title);
195 for (Thread t : tinkerThreads) {
196 String name = t.getName();
197 if (name.equals(title)) {
198 tinkerThreads.remove(t);
199 break;
200 }
201 }
202 if (resultsTabbedPane.getComponentCount() == 0) {
203 remove(resultsTabbedPane);
204 add(noLogsPanel, BorderLayout.CENTER);
205 }
206 validate();
207 repaint();
208 }
209 }
210
211
212
213
214
215
216 public JProgressBar getProgressBar() {
217 return statusProgressBar;
218 }
219
220
221 public void selected() {
222 validate();
223 repaint();
224 }
225
226
227
228
229
230
231 public void setDone(String logFileName) {
232 synchronized (this) {
233 if (logFileName == null) {
234 return;
235 }
236 File logFile = new File(logFileName);
237 for (Thread thread : tinkerThreads) {
238 String jobName = thread.getName();
239 if (jobName.equals(logFileName)) {
240 tinkerThreads.remove(thread);
241 break;
242 }
243 }
244 if (!logFile.exists()) {
245 return;
246 }
247 if (logFiles.containsKey(logFile.getAbsolutePath())) {
248 JTextArea logTextArea = logFiles.get(logFile.getAbsolutePath());
249 loadText(logTextArea, logFile);
250 }
251 else {
252 addPane(logFile);
253 }
254 resultsTabbedPane.setSelectedIndex(resultsTabbedPane.indexOfTab(logFile.getAbsolutePath()));
255 refreshStatus();
256 }
257 }
258
259
260
261
262
263
264 public String toString() {
265 return "Logging";
266 }
267
268 private void addPane(File logFile) {
269 if (!logFile.exists()) {
270 return;
271 }
272 JTextArea logTextArea = new JTextArea();
273 logTextArea.setEditable(logFile.canWrite());
274 logTextArea.setFont(font);
275 logFiles.put(logFile.getAbsolutePath(), logTextArea);
276 JScrollPane scrollPane =
277 new JScrollPane(
278 logTextArea,
279 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
280 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
281 scrollPane.setBorder(eb);
282 resultsTabbedPane.add(scrollPane, logFile.getAbsolutePath());
283 resultsTabbedPane.setSelectedIndex(resultsTabbedPane.getComponentCount() - 1);
284 if (resultsTabbedPane.getComponentCount() == 1) {
285 remove(noLogsPanel);
286 add(resultsTabbedPane, BorderLayout.CENTER);
287 validate();
288 repaint();
289 }
290 loadText(logTextArea, logFile);
291 }
292
293
294 private void closeAll() {
295 synchronized (this) {
296 resultsTabbedPane.removeAll();
297 logFiles.clear();
298 tinkerThreads.clear();
299 }
300 }
301
302 private void initToolBar() {
303 toolBar = new JToolBar("Results");
304 toolBar.setLayout(new FlowLayout(FlowLayout.LEFT));
305 JButton jbrefresh =
306 new JButton(
307 new ImageIcon(
308 getClass().getClassLoader().getResource("ffx/ui/icons/page_refresh.png")));
309 jbrefresh.setActionCommand("Refresh");
310 jbrefresh.setToolTipText("Refresh the Logs Panel");
311 jbrefresh.addActionListener(this);
312 Insets insets = jbrefresh.getInsets();
313 insets.top = 2;
314 insets.bottom = 2;
315 insets.left = 2;
316 insets.right = 2;
317 jbrefresh.setMargin(insets);
318 toolBar.add(jbrefresh);
319 toolBar.addSeparator();
320 JButton jbopen =
321 new JButton(
322 new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/page_open.png")));
323 jbopen.setActionCommand("Open...");
324 jbopen.setToolTipText("Open any Text File");
325 jbopen.addActionListener(this);
326 jbopen.setMargin(insets);
327 toolBar.add(jbopen);
328 JButton jbsave =
329 new JButton(
330 new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/disk.png")));
331 jbsave.setActionCommand("Save");
332 jbsave.setToolTipText("Save the Active File");
333 jbsave.addActionListener(this);
334 jbsave.setMargin(insets);
335 toolBar.add(jbsave);
336 JButton jbsaveas =
337 new JButton(
338 new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/page_save.png")));
339 jbsaveas.setActionCommand("Save As...");
340 jbsaveas.setToolTipText("Save the Active Text File Under a New Name");
341 jbsaveas.addActionListener(this);
342 jbsaveas.setMargin(insets);
343 toolBar.add(jbsaveas);
344 JButton jbclose =
345 new JButton(
346 new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/cancel.png")));
347 jbclose.setActionCommand("Close");
348 jbclose.setToolTipText("Close the Active Text File");
349 jbclose.addActionListener(this);
350 jbclose.setMargin(insets);
351 toolBar.add(jbclose);
352 JButton jbcloseall =
353 new JButton(
354 new ImageIcon(getClass().getClassLoader().getResource("ffx/ui/icons/stop.png")));
355 jbcloseall.setActionCommand("Close All");
356 jbcloseall.setToolTipText("Close All Open Text Files");
357 jbcloseall.addActionListener(this);
358 jbcloseall.setMargin(insets);
359 toolBar.add(jbcloseall);
360 toolBar.setFloatable(false);
361 toolBar.setRollover(true);
362 toolBar.setOrientation(JToolBar.HORIZONTAL);
363 }
364
365 private void loadText(JTextArea logTextArea, File logFile) {
366 if (logTextArea == null || (!logFile.exists()) || (!logFile.canRead())) {
367 return;
368 }
369 logTextArea.setText("");
370 try {
371 FileInputStream inputStream = new FileInputStream(logFile);
372 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
373 while (bufferedReader.ready()) {
374 logTextArea.append(bufferedReader.readLine() + "\n");
375 }
376 bufferedReader.close();
377 inputStream.close();
378 } catch (IOException e) {
379 logger.severe("" + e);
380 }
381
382 }
383
384
385 private void refresh() {
386 synchronized (tinkerThreads) {
387 for (Thread t : tinkerThreads) {
388 File file = new File(t.getName());
389 if (!file.exists()) {
390 continue;
391 }
392
393 if (logFiles.containsKey(file.getAbsolutePath())) {
394 JTextArea ta = logFiles.get(file.getAbsolutePath());
395 loadText(ta, file);
396 }
397 else {
398 addPane(file);
399 }
400 }
401 }
402 refreshStatus();
403 validate();
404 repaint();
405 }
406
407
408 private void refreshStatus() {
409 int count = tinkerThreads.size();
410 if (count == 0) {
411 statusProgressBar.setString("");
412 statusProgressBar.setIndeterminate(false);
413 } else if (count == 1) {
414 statusProgressBar.setString("1 Job Running");
415 statusProgressBar.setIndeterminate(true);
416 } else {
417 statusProgressBar.setString(count + " Jobs Running");
418 statusProgressBar.setIndeterminate(true);
419 }
420 }
421
422 private void saveSelected() {
423 int index = resultsTabbedPane.getSelectedIndex();
424 if (index < 0) {
425 return;
426 }
427 String title = resultsTabbedPane.getTitleAt(index);
428 JTextArea logTextArea = logFiles.get(title);
429 File logFile = new File(title);
430 if (logTextArea != null && logFile.exists() && logFile.canWrite()) {
431 try {
432 FileOutputStream outputStream = new FileOutputStream(logFile);
433 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
434 bw.write(logTextArea.getText());
435 bw.close();
436 outputStream.close();
437 } catch (IOException e) {
438 logger.severe("" + e);
439 }
440 }
441 }
442
443 private void saveSelectedAs() {
444 synchronized (resultsTabbedPane) {
445 int index = resultsTabbedPane.getSelectedIndex();
446 if (index < 0) {
447 return;
448 }
449 String title = resultsTabbedPane.getTitleAt(index);
450 JTextArea logTextArea = logFiles.get(title);
451 File logFile = new File(title);
452 if (logTextArea != null && logFile.exists() && logFile.canWrite()) {
453 JFileChooser fileChooser = MainPanel.resetFileChooser();
454 fileChooser.setSelectedFile(logFile);
455 fileChooser.setAcceptAllFileFilterUsed(true);
456 int result = fileChooser.showSaveDialog(this);
457 if (result == JFileChooser.APPROVE_OPTION) {
458 logFile = fileChooser.getSelectedFile();
459 } else {
460 return;
461 }
462 try {
463 logFiles.remove(title);
464 FileOutputStream outputStream = new FileOutputStream(logFile);
465 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
466 bw.write(logTextArea.getText());
467 bw.close();
468 outputStream.close();
469 resultsTabbedPane.setTitleAt(index, logFile.getAbsolutePath());
470 logFiles.put(logFile.getAbsolutePath(), logTextArea);
471 } catch (IOException e) {
472 logger.severe("" + e);
473 }
474 }
475 }
476 }
477 }