source: src/main/java/weka/gui/LogPanel.java @ 6

Last change on this file since 6 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 10.7 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    LogPanel.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui;
24
25import java.awt.BorderLayout;
26import java.awt.Point;
27import java.awt.event.ActionEvent;
28import java.awt.event.ActionListener;
29import java.awt.event.InputEvent;
30import java.awt.event.MouseAdapter;
31import java.awt.event.MouseEvent;
32import java.awt.event.WindowAdapter;
33import java.awt.event.WindowEvent;
34import java.text.SimpleDateFormat;
35import java.util.Date;
36
37import javax.swing.BorderFactory;
38import javax.swing.JButton;
39import javax.swing.JFrame;
40import javax.swing.JLabel;
41import javax.swing.JMenuItem;
42import javax.swing.JPanel;
43import javax.swing.JPopupMenu;
44import javax.swing.JScrollPane;
45import javax.swing.JTextArea;
46import javax.swing.JViewport;
47import javax.swing.event.ChangeEvent;
48import javax.swing.event.ChangeListener;
49
50/**
51 * This panel allows log and status messages to be posted. Log messages
52 * appear in a scrollable text area, and status messages appear as one-line
53 * transient messages.
54 *
55 * @author Len Trigg (trigg@cs.waikato.ac.nz)
56 * @version $Revision: 4789 $
57 */
58public class LogPanel
59  extends JPanel
60  implements Logger, TaskLogger {
61
62  /** for serialization */
63  private static final long serialVersionUID = -4072464549112439484L;
64
65  /** Displays the current status */
66  protected JLabel m_StatusLab = new JLabel("OK");
67 
68  /** Displays the log messages */
69  protected JTextArea m_LogText = new JTextArea(4, 20);
70
71  /** The button for viewing the log */
72  protected JButton m_logButton = new JButton("Log");
73
74  /** An indicator for whether text has been output yet */
75  protected boolean m_First = true;
76
77  /** The panel for monitoring the number of running tasks (if supplied)*/
78  protected WekaTaskMonitor m_TaskMonitor=null;
79 
80  /**
81   * Creates the log panel with no task monitor and
82   * the log always visible.
83   */
84  public LogPanel() {
85
86    this(null, false, false, true);
87  }
88
89  /**
90   * Creates the log panel with a task monitor,
91   * where the log is hidden.
92   *
93   * @param tm the task monitor, or null for none
94   */
95  public LogPanel(WekaTaskMonitor tm) {
96
97    this(tm, true, false, true);
98  }
99
100  /**
101   * Creates the log panel, possibly with task monitor,
102   * where the log is optionally hidden.
103   *
104   * @param tm the task monitor, or null for none
105   * @param logHidden true if the log should be hidden and
106   *                  acessible via a button, or false if the
107   *                  log should always be visible.
108   */
109  public LogPanel(WekaTaskMonitor tm, boolean logHidden) {
110    this(tm, logHidden, false, true);
111  }
112
113  /**
114   * Creates the log panel, possibly with task monitor,
115   * where the either the log is optionally hidden or the status
116   * (having both hidden is not allowed).
117   *
118   *
119   * @param tm the task monitor, or null for none
120   * @param logHidden true if the log should be hidden and
121   *                  acessible via a button, or false if the
122   *                  log should always be visible.
123   * @param statusHidden true if the status bar should be hidden (i.e.
124   * @param titledBorder true if the log should have a title
125   * you only want the log part).
126   */
127  public LogPanel(WekaTaskMonitor tm, boolean logHidden, 
128      boolean statusHidden, boolean titledBorder) {
129
130    m_TaskMonitor = tm;
131    m_LogText.setEditable(false);
132    m_LogText.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
133    m_StatusLab.setBorder(BorderFactory.createCompoundBorder(
134                          BorderFactory.createTitledBorder("Status"),
135                          BorderFactory.createEmptyBorder(0, 5, 5, 5)));
136
137    // create scrolling log
138    final JScrollPane js = new JScrollPane(m_LogText);
139    js.getViewport().addChangeListener(new ChangeListener() {
140      private int lastHeight;
141      public void stateChanged(ChangeEvent e) {
142        JViewport vp = (JViewport)e.getSource();
143        int h = vp.getViewSize().height; 
144        if (h != lastHeight) { // i.e. an addition not just a user scrolling
145          lastHeight = h;
146          int x = h - vp.getExtentSize().height;
147          vp.setViewPosition(new Point(0, x));
148        }
149      }
150    });
151
152    if (logHidden) {
153
154      // create log window
155      final JFrame jf = new JFrame("Log");
156      jf.addWindowListener(new WindowAdapter() {
157          public void windowClosing(WindowEvent e) {
158            jf.setVisible(false);
159          }
160        });
161      jf.getContentPane().setLayout(new BorderLayout());
162      jf.getContentPane().add(js, BorderLayout.CENTER);
163      jf.pack();
164      jf.setSize(450, 350);
165     
166      // display log window on request
167      m_logButton.addActionListener(new ActionListener() {
168          public void actionPerformed(ActionEvent e) {
169            jf.setVisible(true);
170          }
171        });
172     
173      // do layout
174      setLayout(new BorderLayout());
175      JPanel logButPanel = new JPanel();
176      logButPanel.setLayout(new BorderLayout());
177      logButPanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
178      logButPanel.add(m_logButton, BorderLayout.CENTER);
179      JPanel p1 = new JPanel();
180      p1.setLayout(new BorderLayout());
181      p1.add(m_StatusLab, BorderLayout.CENTER);
182      p1.add(logButPanel, BorderLayout.EAST);
183     
184      if (tm == null) {
185        add(p1, BorderLayout.SOUTH);
186      } else {
187        JPanel p2 = new JPanel();
188        p2.setLayout(new BorderLayout());
189        p2.add(p1, BorderLayout.CENTER);
190        p2.add((java.awt.Component)m_TaskMonitor, BorderLayout.EAST);
191        add(p2, BorderLayout.SOUTH);
192      }
193    } else {
194      // log always visible
195     
196      JPanel p1 = new JPanel();
197      if (titledBorder) {
198        p1.setBorder(BorderFactory.createTitledBorder("Log"));
199      }
200      p1.setLayout(new BorderLayout());
201      p1.add(js, BorderLayout.CENTER);
202      setLayout(new BorderLayout());
203      add(p1, BorderLayout.CENTER);
204
205      if (tm == null) {
206        if (!statusHidden) {
207          add(m_StatusLab, BorderLayout.SOUTH);
208        }
209      } else {
210        if (!statusHidden) {
211          JPanel p2 = new JPanel();
212          p2.setLayout(new BorderLayout());
213          p2.add(m_StatusLab,BorderLayout.CENTER);
214          p2.add((java.awt.Component)m_TaskMonitor, BorderLayout.EAST);
215          add(p2, BorderLayout.SOUTH);
216        }
217      }
218    }
219    addPopup();
220  }
221
222  /**
223   * adds thousand's-separators to the number
224   * @param l       the number to print
225   * @return        the number as string with separators
226   */
227  private String printLong(long l) {
228    String        result;
229    String        str;
230    int           i;
231    int           count;
232
233    str    = Long.toString(l);
234    result = "";
235    count  = 0;
236
237    for (i = str.length() - 1; i >= 0; i--) {
238      count++;
239      result = str.charAt(i) + result;
240      if ( (count == 3) && (i > 0) ) {
241        result = "," + result;
242        count = 0;
243      }
244    }
245   
246    return result;
247  }
248
249  /**
250   * Add a popup menu for displaying the amount of free memory
251   * and running the garbage collector
252   */
253  private void addPopup() {
254    addMouseListener(new MouseAdapter() {
255        public void mouseClicked(MouseEvent e) {
256          if (((e.getModifiers() & InputEvent.BUTTON1_MASK)
257               != InputEvent.BUTTON1_MASK) || e.isAltDown()) {
258            JPopupMenu gcMenu = new JPopupMenu();
259            JMenuItem availMem = new JMenuItem("Memory information");
260            availMem.addActionListener(new ActionListener() {
261                public void actionPerformed(ActionEvent ee) {
262                  System.gc();
263                  Runtime currR = Runtime.getRuntime();
264                  long freeM = currR.freeMemory();
265                  long totalM = currR.totalMemory();
266                  long maxM = currR.maxMemory();
267                  logMessage("Memory (free/total/max.) in bytes: " + printLong(freeM) + " / " + printLong(totalM) + " / " + printLong(maxM));
268                  statusMessage("Memory (free/total/max.) in bytes: " + printLong(freeM) + " / " + printLong(totalM) + " / " + printLong(maxM));
269                }
270              });
271            gcMenu.add(availMem);
272            JMenuItem runGC = new JMenuItem("Run garbage collector");
273            runGC.addActionListener(new ActionListener() {
274                public void actionPerformed(ActionEvent ee) {
275                  statusMessage("Running garbage collector");
276                  System.gc();
277                  statusMessage("OK");
278                }
279              });
280            gcMenu.add(runGC);
281            gcMenu.show(LogPanel.this, e.getX(), e.getY());
282          }
283        }
284      });
285  }
286
287  /**
288   * Record the starting of a new task
289   */
290  public void taskStarted() {
291    if (m_TaskMonitor != null) {
292      m_TaskMonitor.taskStarted();
293    }
294  }
295
296  /**
297   * Record a task ending
298   */
299  public void taskFinished() {
300    if (m_TaskMonitor != null) {
301      m_TaskMonitor.taskFinished();
302    }
303  }
304   
305  /**
306   * Gets a string containing current date and time.
307   *
308   * @return a string containing the date and time.
309   */
310  protected static String getTimestamp() {
311
312    return (new SimpleDateFormat("HH:mm:ss:")).format(new Date());
313  }
314
315  /**
316   * Sends the supplied message to the log area. The current timestamp will
317   * be prepended.
318   *
319   * @param message a value of type 'String'
320   */
321  public synchronized void logMessage(String message) {
322
323    if (m_First) {
324      m_First = false;
325    } else {
326      m_LogText.append("\n");
327    }
328    m_LogText.append(LogPanel.getTimestamp() + ' ' + message);
329    weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, message);
330  }
331
332  /**
333   * Sends the supplied message to the status line.
334   *
335   * @param message the status message
336   */
337  public synchronized void statusMessage(String message) {
338
339    m_StatusLab.setText(message);
340  }
341
342 
343  /**
344   * Tests out the log panel from the command line.
345   *
346   * @param args ignored
347   */
348  public static void main(String [] args) {
349
350    try {
351      final javax.swing.JFrame jf = new javax.swing.JFrame("Log Panel");
352      jf.getContentPane().setLayout(new BorderLayout());
353      final LogPanel lp = new LogPanel();
354      jf.getContentPane().add(lp, BorderLayout.CENTER);
355      jf.addWindowListener(new java.awt.event.WindowAdapter() {
356        public void windowClosing(java.awt.event.WindowEvent e) {
357          jf.dispose();
358          System.exit(0);
359        }
360      });
361      jf.pack();
362      jf.setVisible(true);
363      lp.logMessage("Welcome to the generic log panel!");
364      lp.statusMessage("Hi there");
365      lp.logMessage("Funky chickens");
366     
367    } catch (Exception ex) {
368      ex.printStackTrace();
369      System.err.println(ex.getMessage());
370    }
371  }
372}
Note: See TracBrowser for help on using the repository browser.