jTracer  1.03
Stack trace visualization tool
MainFrame.java
Go to the documentation of this file.
1 
7 package org.libcsdbg.jtracer;
8 
9 import java.util.Enumeration;
10 
11 import java.io.File;
12 import java.io.FileOutputStream;
13 import java.io.IOException;
14 
15 import java.net.URL;
16 import java.net.Socket;
17 import java.net.ServerSocket;
18 import java.net.InetAddress;
19 import java.net.InetSocketAddress;
20 
21 import java.nio.channels.FileLock;
22 
23 import java.beans.PropertyChangeEvent;
24 import java.beans.PropertyChangeListener;
25 
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.awt.Insets;
29 import java.awt.Dimension;
30 import java.awt.BorderLayout;
31 import java.awt.GridBagLayout;
32 import java.awt.GridBagConstraints;
33 import java.awt.GraphicsEnvironment;
34 import java.awt.GraphicsDevice;
35 
36 import javax.swing.JFrame;
37 import javax.swing.JPanel;
38 import javax.swing.JScrollPane;
39 import javax.swing.UIManager;
40 
52 public class MainFrame extends JFrame implements
53  Runnable,
54  ActionListener,
55  PropertyChangeListener
56 {
58  private static final long serialVersionUID = 0x1000;
59 
61  private ToolBar tools = null;
62 
64  private MenuBar menu = null;
65 
67  private LogPane log = null;
68 
70  private StatusBar status = null;
71 
73  private AboutDialog about = null;
74 
76  private FileLock lock = null;
77 
79  private Thread server = null;
80 
82  private ServerSocket listener = null;
83 
85  private SessionManager desktop = null;
86 
87 
91  MainFrame()
92  {
93  super();
94 
95  Registry conf = Registry.getCurrent();
96  setTitle((String) conf.get("generic", "name"));
97  setIconImages(conf.getProjectIcons());
98 
99  menu = new MenuBar(this);
100  tools = new ToolBar(this);
101  log = new LogPane();
102  status = new StatusBar("jTracer initialized");
103  desktop = new SessionManager(this);
104 
105  setJMenuBar(menu);
106  add(tools, BorderLayout.NORTH);
107  add(status, BorderLayout.SOUTH);
108 
109  JPanel nowrap = new JPanel(new BorderLayout());
110  nowrap.add(log);
111  JScrollPane viewport = new JScrollPane(nowrap);
112  viewport.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
113 
114  GridBagLayout lm = new GridBagLayout();
115  GridBagConstraints c = new GridBagConstraints();
116  JPanel inset = new JPanel(lm);
117  c.weightx = c.weighty = 1;
118  c.fill = GridBagConstraints.BOTH;
119  c.insets = new Insets(0, 2, 0, 1);
120  lm.setConstraints(viewport, c);
121  inset.add(viewport);
122  add(inset, BorderLayout.CENTER);
123 
124  addPropertyChangeListener("isServing", menu);
125  addPropertyChangeListener("isServing", tools);
126  addPropertyChangeListener("hasClients", menu);
127  addPropertyChangeListener("hasClients", tools);
128  addWindowListener(desktop);
129 
130  firePropertyChange("isServing", null, false);
131  firePropertyChange("hasClients", null, false);
132 
133  log.appendln("jTracer initialized", "status");
134  log.appendln("Ready to start serving", "status");
135 
136  setSize((Dimension) conf.get("generic", "size"));
137  setLocationRelativeTo(null);
138  }
139 
140 
144  public void startService()
145  {
146  if (server != null)
147  return;
148 
149  log.appendln("Starting server...", "status");
150  server = new Thread(this, "server");
151  server.setDaemon(true);
152  server.start();
153  }
154 
155 
159  public void stopService()
160  {
161  if (server == null)
162  return;
163 
164  log.appendln("Stopping server...", "status");
165  Thread thr = server;
166  shutdown();
167 
168  try {
169  if (thr.isAlive())
170  thr.join();
171  }
172 
173  catch (Throwable t) {
174  Registry.debug(t);
175  }
176 
177  log.appendln("Service stopped. All incoming connections dropped", "status");
178  }
179 
180 
184  public void shutdown()
185  {
186  try {
187  server = null;
188 
189  if (listener != null) {
190  listener.close();
191  listener = null;
192  }
193  }
194 
195  catch (Throwable t) {
196  Registry.debug(t);
197  }
198  }
199 
200 
206  public static void main(String[] argv)
207  {
208  try {
209  Registry conf = new Registry();
210  conf.setup();
211 
212  Highlighter h = new Highlighter();
213  MainFrame app = new MainFrame();
214 
215  File lockf = conf.getResource("log/.lock");
216  FileOutputStream fs = new FileOutputStream(lockf);
217 
218  app.lock = fs.getChannel().tryLock();
219  if (app.lock == null) {
220  String nm = (String) conf.get("generic", "name");
221  Alert.error(null, nm + " is already running", true);
222  }
223 
224  lockf.deleteOnExit();
225  UIManager.setLookAndFeel((String) conf.get("generic", "lnf"));
226  app.setVisible(true);
227  }
228 
229  catch (Throwable t) {
230  Registry.debug(t);
231  System.exit(1);
232  }
233  }
234 
235 
239  public void run()
240  {
241  try {
242  Registry conf = Registry.getCurrent();
243  Enumeration keys = conf.getSectionKeys("server");
244  if (keys == null)
245  throw new Exception("No server configuration found");
246 
247  /* Create the listener socket unbound */
248  listener = new ServerSocket();
249  listener.setReuseAddress(true);
250 
251  /* Bind to one or more interfaces */
252  InetSocketAddress iface = null;
253  while (keys.hasMoreElements()) {
254  String key = (String) keys.nextElement();
255 
256  iface = (InetSocketAddress) conf.get("server", key);
257  listener.bind(iface);
258 
259  InetAddress addr = iface.getAddress();
260  String msg = "Accepting connections @";
261  msg += addr.getHostAddress() + ":" + iface.getPort();
262 
263  if (addr.isAnyLocalAddress())
264  msg += " (all local)";
265 
266  else if (addr.isMulticastAddress())
267  msg += " (multicast)";
268 
269  else
270  msg += " (" + addr.getCanonicalHostName() + ")";
271 
272  log.appendln(msg, "status");
273  }
274 
275  if (iface == null || !listener.isBound())
276  throw new Exception("No server configuration found");
277 
278  firePropertyChange("isServing", null, true);
279  status.startUptimeTimer();
280 
281  /* Listen for incoming connections */
282  while (server == Thread.currentThread()) {
283  status.setMessage("Waiting for connections", true);
284 
285  try {
286  Socket peer = listener.accept();
287 
288  String addr = peer.getInetAddress().getHostAddress();
289  int port = peer.getPort();
290  log.appendln("Connected peer @" + addr + ":" + port, "status");
291 
292  desktop.register(peer);
293  }
294 
295  catch (Throwable t) {
296  log.appendln(t.toString(), "alert");
297  if (!(t instanceof IOException))
298  Registry.debug(t);
299  }
300  }
301 
302  status.stopUptimeTimer();
303  status.setMessage("Service complete", true);
304  firePropertyChange("isServing", null, false);
305  }
306 
307  catch (Throwable t) {
308  Registry.debug(t);
309  getToolkit().beep();
310  shutdown();
311 
312  log.appendln("Failed to start server (" + t.toString() + ")", "error");
313  status.setMessage("Server failed", false);
314  }
315  }
316 
317 
323  public void actionPerformed(ActionEvent event)
324  {
325  try {
326  String cmd = event.getActionCommand();
327 
328  /* Service menu commands */
329  if (cmd.equals("Start"))
330  startService();
331 
332  else if (cmd.equals("Stop"))
333  stopService();
334 
335  else if (cmd.equals("Restart")) {
336  log.appendln("Restarting server (reload configuration)...", "status");
337  stopService();
338  startService();
339  }
340 
341  else if (cmd.equals("Clear log"))
342  log.clear();
343 
344  else if (cmd.equals("Quit")) {
345  boolean reply = Alert.prompt(this, "Are you sure you want to quit?");
346  if (reply)
347  System.exit(0);
348  }
349 
350 
351  /* View menu commands */
352  else if (cmd.equals("Toolbar")) {
353  if (menu.getToggleState(0))
354  add(tools, BorderLayout.NORTH);
355  else
356  remove(tools);
357 
358  validate();
359  }
360 
361  else if (cmd.equals("Statusbar")) {
362  if (menu.getToggleState(1))
363  add(status, BorderLayout.SOUTH);
364  else
365  remove(status);
366 
367  validate();
368  }
369 
370  else if (cmd.equals("Find"))
371  Alert.error(this, "Not implemented yet", false);
372 
373  else if (cmd.equals("Preferences"))
374  Alert.error(this, "Not implemented yet", false);
375 
376  else if (cmd.equals("Always on top")) {
377  boolean state = menu.getToggleState(2);
378  setAlwaysOnTop(state);
379  desktop.setAlwaysOnTop(-1, state);
380  }
381 
382  else if (cmd.equals("Full screen")) {
383  GraphicsEnvironment env;
384  env = GraphicsEnvironment.getLocalGraphicsEnvironment();
385 
386  GraphicsDevice dev = env.getDefaultScreenDevice();
387  if (!dev.isFullScreenSupported())
388  return;
389 
390  JFrame cur = (JFrame) dev.getFullScreenWindow();
391  if (cur == null)
392  dev.setFullScreenWindow(this);
393  else
394  dev.setFullScreenWindow(null);
395  }
396 
397 
398  /* Client menu commands */
399  else if (cmd.equals("Select previous"))
401 
402  else if (cmd.equals("Select next"))
404 
405  else if (cmd.equals("Close")) {
406  /* This fixes a very tricky bug induced by the OS window manager */
407  toFront();
408  desktop.disposeCurrent();
409  }
410 
411  else if (cmd.equals("Cascade"))
412  desktop.cascade();
413 
414  else if (cmd.equals("Minimize all"))
415  desktop.setIconified(true);
416 
417  else if (cmd.equals("Restore all"))
418  desktop.setIconified(false);
419 
420  else if (cmd.equals("Close all")) {
421  boolean reply = Alert.prompt(this, "Close all client windows?");
422  if (!reply)
423  return;
424 
425  desktop.disposeAll();
426  }
427 
428  else if (cmd.startsWith("Select session")) {
429  String parts[] = cmd.split("\\s");
430  desktop.setCurrent(Integer.valueOf(parts[2]));
431  }
432 
433  /* Help menu commands */
434  else if (
435  cmd.equals("Online documentation") ||
436  cmd.equals("Bug tracker") ||
437  cmd.equals("Submit feedback")
438  ) {
439  Registry conf = Registry.getCurrent();
440  String key = "url-" + cmd.toLowerCase().replace(' ', '-');
441  conf.browse((URL) conf.get("generic", key));
442  }
443 
444  else if (cmd.equals("Check for updates"))
445  Alert.error(this, "Not implemented yet", false);
446 
447  else if (cmd.startsWith("About")) {
448  if (about == null)
449  about = new AboutDialog(this);
450 
451  about.setLocationRelativeTo(this);
452  about.setVisible(true);
453  }
454 
455 
456  /* Session commands /
457  else if (cmd.equals("Remove trace"))
458  setStatus(null, true); */
459  }
460 
461  catch (Throwable t) {
462  Registry.debug(t);
463  }
464  }
465 
466 
472  public void propertyChange(PropertyChangeEvent event)
473  {
474  try {
475  String key = event.getPropertyName();
476  Object val = event.getNewValue();
477 
478  if (key.equals("sessionCount")) {
479  firePropertyChange("hasClients", null, (Integer) val != 0);
480  menu.listSessions(desktop.getSessions(), desktop.getCurrent());
481  status.setIndicators(desktop.getSessionCount(), desktop.getTraceCount());
482  }
483 
484  else if (key.equals("traceCount")) {
485  menu.listSessions(desktop.getSessions(), desktop.getCurrent());
486  status.setIndicators(desktop.getSessionCount(), desktop.getTraceCount());
487  }
488 
489  else if (key.equals("currentSession"))
490  menu.setSelectedSession((Integer) val);
491 
492  else if (key.equals("sessionRequest"))
493  log.appendln((String) val, "data");
494  }
495 
496  catch (Throwable t) {
497  Registry.debug(t);
498  }
499  }
500 }
501 
ToolBar tools
Application toolbar.
Definition: MainFrame.java:61
AboutDialog about
About dialog.
Definition: MainFrame.java:73
Object get(String section, String key)
Get an entry.
Definition: Registry.java:151
void propertyChange(PropertyChangeEvent event)
Handler for events fired when UI properties change.
Definition: MainFrame.java:472
FileLock lock
Unique server lock.
Definition: MainFrame.java:76
Configuration registry.
Definition: Registry.java:41
Application statusbar with multiple indicators and configurable styles.
Definition: StatusBar.java:32
Main application logging pane.
Definition: LogPane.java:27
static final long serialVersionUID
Class version.
Definition: MainFrame.java:58
Thread server
Server thread.
Definition: MainFrame.java:79
Vector< Image > getProjectIcons()
Get a cross-platform set of project icons.
Definition: Registry.java:305
LogPane log
Application logging pane.
Definition: MainFrame.java:67
void appendln(String ln, String tag)
Append a line of formatted text and a line break.
Definition: LogPane.java:155
void shutdown()
Close the listening server socket and shutdown the server.
Definition: MainFrame.java:184
Main application toolbar equipped with a dynamic UI updating mechanism.
Definition: ToolBar.java:23
static void main(String[] argv)
Process entry point.
Definition: MainFrame.java:206
void setSelectedSession(int sel)
Update the session list menu to show the currently selected session.
Definition: MenuBar.java:141
void stopService()
Stop the server.
Definition: MainFrame.java:159
StatusBar status
Application statusbar.
Definition: MainFrame.java:70
Main application window frame and process entry point.
Definition: MainFrame.java:52
void setIconified(final boolean how)
Minimize or restore all client windows.
MenuBar menu
Application menu.
Definition: MainFrame.java:64
void actionPerformed(ActionEvent event)
Handler for toolbar and menu action events.
Definition: MainFrame.java:323
static void error(JFrame owner, String msg, boolean fatal)
Show an error alert and exit if the error is marked as fatal.
Definition: Alert.java:165
void run()
Server thread implementation.
Definition: MainFrame.java:239
void shiftSelection(int step)
Select the previous/next not iconified client window.
C++ stack trace syntax highlighter.
Main application menubar equipped with a dynamic UI updating mechanism.
Definition: MenuBar.java:35
A dialog that shows an HTML page with project information (version, short description, license, copyright e.t.c) and links to various online project resources.
int getTraceCount()
Get the total number of traces.
User alert or simple prompt dialog with configurable styles.
Definition: Alert.java:29
ServerSocket listener
Listener socket.
Definition: MainFrame.java:82
boolean getToggleState(int index)
Get the state of a toggle menu item.
Definition: MenuBar.java:210
void clear()
Remove all contents.
Definition: LogPane.java:164
void startService()
Start the server.
Definition: MainFrame.java:144
SessionManager desktop
Main and window manager.
Definition: MainFrame.java:85