PageRenderTime 105ms CodeModel.GetById 81ms app.highlight 20ms RepoModel.GetById 0ms app.codeStats 1ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/gui/LogViewer.java

#
Java | 560 lines | 456 code | 54 blank | 50 comment | 49 complexity | d4a1aced8fc1618ffeaaa09a984996ef MD5 | raw file
  1/*
  2 * LogViewer.java
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 1999, 2004 Slava Pestov
  7 *
  8 * This program is free software; you can redistribute it and/or
  9 * modify it under the terms of the GNU General Public License
 10 * as published by the Free Software Foundation; either version 2
 11 * of the License, or any later version.
 12 *
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 *
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program; if not, write to the Free Software
 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 21 */
 22
 23package org.gjt.sp.jedit.gui;
 24
 25//{{{ Imports
 26import java.awt.*;
 27import java.awt.event.*;
 28import javax.swing.*;
 29import javax.swing.border.EmptyBorder;
 30import javax.swing.event.*;
 31import org.gjt.sp.jedit.*;
 32import org.gjt.sp.jedit.EditBus.EBHandler;
 33import org.gjt.sp.jedit.msg.PropertiesChanged;
 34import org.gjt.sp.util.Log;
 35import org.gjt.sp.util.ThreadUtilities;
 36//}}}
 37
 38/**
 39 * @version $Id: LogViewer.java 19134 2010-12-14 16:21:58Z daleanson $
 40 */
 41public class LogViewer extends JPanel implements DefaultFocusComponent
 42{
 43	//{{{ LogViewer constructor
 44	public LogViewer()
 45	{
 46		super(new BorderLayout());
 47		setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0));
 48		JPanel caption = new JPanel();
 49		caption.setLayout(new BoxLayout(caption,BoxLayout.X_AXIS));
 50		caption.setBorder(new EmptyBorder(6, 0, 6, 0));
 51
 52		String settingsDirectory = jEdit.getSettingsDirectory();
 53		if(settingsDirectory != null)
 54		{
 55			String[] args = { MiscUtilities.constructPath(
 56								      settingsDirectory, "activity.log") };
 57			JLabel label = new JLabel(jEdit.getProperty(
 58								    "log-viewer.caption",args));
 59			caption.add(label);
 60		}
 61
 62		caption.add(Box.createHorizontalGlue());
 63
 64		tailIsOn = jEdit.getBooleanProperty("log-viewer.tail", false);
 65		tail = new JCheckBox(
 66				     jEdit.getProperty("log-viewer.tail.label"),tailIsOn);
 67		tail.addActionListener(new ActionHandler());
 68
 69
 70		filter = new JTextField();
 71		filter.getDocument().addDocumentListener(new DocumentListener()
 72		{
 73			@Override
 74			public void changedUpdate(DocumentEvent e)
 75			{
 76				setFilter();
 77			}
 78
 79			@Override
 80			public void insertUpdate(DocumentEvent e)
 81			{
 82				setFilter();
 83			}
 84
 85			@Override
 86			public void removeUpdate(DocumentEvent e)
 87			{
 88				setFilter();
 89			}
 90		});
 91		caption.add(filter);
 92		caption.add(tail);
 93
 94		caption.add(Box.createHorizontalStrut(12));
 95
 96		copy = new JButton(jEdit.getProperty("log-viewer.copy"));
 97		copy.addActionListener(new ActionHandler());
 98		caption.add(copy);
 99		
100		caption.add(Box.createHorizontalStrut(6));
101		
102		JButton settings = new JButton(jEdit.getProperty("log-viewer.settings.label"));
103		settings.addActionListener(new ActionListener()
104		{
105			@Override
106			public void actionPerformed(ActionEvent ae)
107			{
108				new LogSettings();
109			}
110		});
111		caption.add(settings);
112
113		ListModel model = Log.getLogListModel();
114		listModel = new MyFilteredListModel(model);
115		// without this, listModel is held permanently in model.
116		// See addNotify() and removeNotify(), and constructor of
117		// FilteredListModel.
118		model.removeListDataListener(listModel);
119
120		list = new LogList(listModel);
121		listModel.setList(list);
122		setFilter();
123
124		add(BorderLayout.NORTH,caption);
125		JScrollPane scroller = new JScrollPane(list);
126		Dimension dim = scroller.getPreferredSize();
127		dim.width = Math.min(600,dim.width);
128		scroller.setPreferredSize(dim);
129		add(BorderLayout.CENTER,scroller);
130
131		propertiesChanged();
132	} //}}}
133
134	//{{{ setBounds() method
135	@Override
136	public void setBounds(int x, int y, int width, int height)
137	{
138		list.setCellRenderer( new ColorizerCellRenderer() );
139		super.setBounds(x, y, width, height);
140		scrollLaterIfRequired();
141	} //}}}
142
143	//{{{ handlePropertiesChanged() method
144	@EBHandler
145	public void handlePropertiesChanged(PropertiesChanged msg)
146	{
147		propertiesChanged();
148	} //}}}
149
150	//{{{ addNotify() method
151	@Override
152	public void addNotify()
153	{
154		super.addNotify();
155		ListModel model = Log.getLogListModel();
156		model.addListDataListener(listModel);
157		model.addListDataListener(listHandler = new ListHandler());
158		if(tailIsOn)
159			scrollToTail();
160
161		EditBus.addToBus(this);
162	} //}}}
163
164	//{{{ removeNotify() method
165	@Override
166	public void removeNotify()
167	{
168		super.removeNotify();
169		ListModel model = Log.getLogListModel();
170		model.removeListDataListener(listModel);
171		model.removeListDataListener(listHandler);
172		listHandler = null;
173		EditBus.removeFromBus(this);
174	} //}}}
175
176	//{{{ focusOnDefaultComponent() method
177	@Override
178	public void focusOnDefaultComponent()
179	{
180		list.requestFocus();
181	} //}}}
182
183	//{{{ Private members
184	private ListHandler listHandler;
185	private final FilteredListModel<ListModel> listModel;
186	private final JList list;
187	private final JButton copy;
188	private final JCheckBox tail;
189	private final JTextField filter;
190	private boolean tailIsOn;
191	private static boolean showDebug = jEdit.getBooleanProperty("log-viewer.message.debug", true);
192	private static boolean showMessage = jEdit.getBooleanProperty("log-viewer.message.message", true);
193	private static boolean showNotice = jEdit.getBooleanProperty("log-viewer.message.notice", true);
194	private static boolean showWarning = jEdit.getBooleanProperty("log-viewer.message.warning", true);
195	private static boolean showError = jEdit.getBooleanProperty("log-viewer.message.error", true);
196
197	//{{{ setFilter() method
198	private void setFilter()
199	{
200		String toFilter = filter.getText();
201		listModel.setFilter(toFilter.length() == 0 ? " " : toFilter);
202		scrollLaterIfRequired();
203	} //}}}
204
205	//{{{ propertiesChanged() method
206	private void propertiesChanged()
207	{
208		list.setFont(jEdit.getFontProperty("view.font"));
209		list.setFixedCellHeight(list.getFontMetrics(list.getFont())
210					.getHeight());
211	} //}}}
212
213	//{{{ scrollToTail() method
214	/** Scroll to the tail of the logs. */
215	private void scrollToTail()
216	{
217		int index = list.getModel().getSize();
218		if(index != 0)
219			list.ensureIndexIsVisible(index - 1);
220	} //}}}
221
222	//{{{ scrollLaterIfRequired() method
223	private void scrollLaterIfRequired()
224	{
225		if (tailIsOn)
226			ThreadUtilities.runInDispatchThread(new Runnable()
227			{
228				@Override
229				public void run()
230				{
231					scrollToTail();
232				}
233			});
234	} //}}}
235
236	//}}}
237
238	//{{{ ActionHandler class
239	private class ActionHandler implements ActionListener
240	{
241		@Override
242		public void actionPerformed(ActionEvent e)
243		{
244			Object src = e.getSource();
245			if(src == tail)
246			{
247				tailIsOn = !tailIsOn;
248				jEdit.setBooleanProperty("log-viewer.tail",tailIsOn);
249				if(tailIsOn)
250				{
251					scrollToTail();
252				}
253			}
254			else if(src == copy)
255			{
256				StringBuilder buf = new StringBuilder();
257				Object[] selected = list.getSelectedValues();
258				if(selected != null && selected.length != 0)
259				{
260					for(int i = 0; i < selected.length; i++)
261					{
262						buf.append(selected[i]);
263						buf.append('\n');
264					}
265				}
266				else
267				{
268					ListModel model = list.getModel();
269					for(int i = 0; i < model.getSize(); i++)
270					{
271						buf.append(model.getElementAt(i));
272						buf.append('\n');
273					}
274				}
275				Registers.setRegister('$',buf.toString());
276			}
277		}
278	} //}}}
279
280	//{{{ ListHandler class
281	private class ListHandler implements ListDataListener
282	{
283		@Override
284		public void intervalAdded(ListDataEvent e)
285		{
286			contentsChanged(e);
287		}
288
289		@Override
290		public void intervalRemoved(ListDataEvent e)
291		{
292			contentsChanged(e);
293		}
294
295		@Override
296		public void contentsChanged(ListDataEvent e)
297		{
298			scrollLaterIfRequired();
299		}
300	} //}}}
301
302	//{{{ LogList class
303	private class LogList extends JList
304	{
305		LogList(ListModel model)
306		{
307			super(model);
308			setVisibleRowCount(24);
309			getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
310			setAutoscrolls(true);
311		}
312
313		@Override
314		public void processMouseEvent(MouseEvent evt)
315		{
316			if(evt.getID() == MouseEvent.MOUSE_PRESSED)
317			{
318				startIndex = list.locationToIndex(evt.getPoint());
319			}
320			super.processMouseEvent(evt);
321		}
322
323		@Override
324		public void processMouseMotionEvent(MouseEvent evt)
325		{
326			if(evt.getID() == MouseEvent.MOUSE_DRAGGED)
327			{
328				int row = list.locationToIndex(evt.getPoint());
329				if(row != -1)
330				{
331					if(startIndex == -1)
332					{
333						list.setSelectionInterval(row,row);
334						startIndex = row;
335					}
336					else
337						list.setSelectionInterval(startIndex,row);
338					list.ensureIndexIsVisible(row);
339					evt.consume();
340				}
341			}
342			else
343				super.processMouseMotionEvent(evt);
344		}
345
346		private int startIndex;
347	} //}}}
348
349	//{{{ ColorizerCellRenderer class
350	private static class ColorizerCellRenderer extends JLabel implements ListCellRenderer
351	{
352
353		// This is the only method defined by ListCellRenderer.
354		// We just reconfigure the JLabel each time we're called.
355		@Override
356		public Component getListCellRendererComponent(
357							      JList list,
358							      Object value,              // value to display
359							      int index,                 // cell index
360							      boolean isSelected,        // is the cell selected
361							      boolean cellHasFocus )     // the list and the cell have the focus
362		{
363			String s = value.toString();
364			setText(s);
365			if (isSelected)
366			{
367				setBackground(list.getSelectionBackground());
368				setForeground(list.getSelectionForeground());
369			}
370			else
371			{
372				setBackground(list.getBackground());
373				Color color = list.getForeground();
374				if (s.contains("[debug]"))
375				{
376					color = jEdit.getColorProperty("log-viewer.message.debug.color", Color.BLUE);
377				}
378				else if (s.contains("[message]"))
379				{
380					color = jEdit.getColorProperty("log-viewer.message.message.color", Color.BLACK);
381				}
382				else if (s.contains("[notice]"))
383				{
384					color = jEdit.getColorProperty("log-viewer.message.notice.color", Color.GREEN);
385				}
386				else if (s.contains("[warning]"))
387				{
388					color = jEdit.getColorProperty("log-viewer.message.warning.color", Color.ORANGE);
389				}
390				else if (s.contains("[error]"))
391				{
392					color = jEdit.getColorProperty("log-viewer.message.error.color", Color.RED);
393				}
394				setForeground( color );
395			}
396			setEnabled( list.isEnabled() );
397			setFont( list.getFont() );
398			setOpaque( true );
399			return this;
400		}
401	} //}}}
402
403	//{{{ MyFilteredListModel
404	private static class MyFilteredListModel extends FilteredListModel<ListModel>
405	{
406		MyFilteredListModel(ListModel model)
407		{
408			super(model);
409		}
410
411		@Override
412		public String prepareFilter(String filter)
413		{
414			return filter.toLowerCase();
415		}
416
417		@Override
418		public boolean passFilter(int row, String filter)
419		{
420			String text = delegated.getElementAt(row).toString().toLowerCase();
421			if (text.contains("[debug]") && !showDebug)
422				return false;
423			if (text.contains("[message]") && !showMessage)
424				return false;
425			if (text.contains("[notice]") && !showNotice)
426				return false;
427			if (text.contains("[warning]") && !showWarning)
428				return false;
429			if (text.contains("[error]") && !showError)
430				return false;
431			return filter.length() == 0 || text.contains(filter);
432		}
433	} //}}}
434	
435	//{{{ LogSettings dialog
436	private class LogSettings extends JDialog
437	{
438		LogSettings() 
439		{
440			super(jEdit.getActiveView(), jEdit.getProperty("log-viewer.dialog.title"));
441			AbstractOptionPane pane = new AbstractOptionPane(jEdit.getProperty("log-viewer.settings.label"))
442			{
443				@Override
444				protected void _init()
445				{
446					setBorder(BorderFactory.createEmptyBorder(11, 11, 12, 12));
447					maxLines = new JSpinner(new SpinnerNumberModel(jEdit.getIntegerProperty("log-viewer.maxlines", 500), 500, Integer.MAX_VALUE, 1));
448					addComponent(jEdit.getProperty("log-viewer.maxlines.label", "Max lines"),
449						maxLines,
450						GridBagConstraints.REMAINDER);
451					addComponent(Box.createVerticalStrut(11));
452					debug = new JCheckBox(jEdit.getProperty("log-viewer.message.debug.label", "Debug"), 
453						jEdit.getBooleanProperty("log-viewer.message.debug", true));
454					message = new JCheckBox(jEdit.getProperty("log-viewer.message.message.label", "Message"),
455						jEdit.getBooleanProperty("log-viewer.message.message", true));
456					notice = new JCheckBox(jEdit.getProperty("log-viewer.message.notice.label", "Notice"),
457						jEdit.getBooleanProperty("log-viewer.message.notice", true));
458					warning = new JCheckBox(jEdit.getProperty("log-viewer.message.warning.label", "Warning"),
459						jEdit.getBooleanProperty("log-viewer.message.warning", true));
460					error = new JCheckBox(jEdit.getProperty("log-viewer.message.error.label", "Error"),
461						jEdit.getBooleanProperty("log-viewer.message.error", true));
462					
463					addComponent(new JLabel(jEdit.getProperty("log-viewer.message.label", "Message Display:")));
464					addComponent(debug,
465						debugColor = new ColorWellButton(
466						jEdit.getColorProperty("log-viewer.message.debug.color", Color.BLUE)),
467						GridBagConstraints.REMAINDER);
468					addComponent(message,
469						messageColor = new ColorWellButton(
470						jEdit.getColorProperty("log-viewer.message.message.color", Color.GREEN)),
471						GridBagConstraints.REMAINDER);
472					addComponent(notice,
473						noticeColor = new ColorWellButton(
474						jEdit.getColorProperty("log-viewer.message.notice.color", Color.GREEN)),
475						GridBagConstraints.REMAINDER);
476					addComponent(warning,
477						warningColor = new ColorWellButton(
478						jEdit.getColorProperty("log-viewer.message.warning.color", Color.ORANGE)),
479						GridBagConstraints.REMAINDER);
480					addComponent(error,
481						errorColor = new ColorWellButton(
482						jEdit.getColorProperty("log-viewer.message.error.color", Color.RED)),
483						GridBagConstraints.REMAINDER);
484					
485					addComponent(Box.createVerticalStrut(11));
486					
487					JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
488					JButton okButton = new JButton(jEdit.getProperty("common.ok"));
489					okButton.addActionListener(new ActionListener()
490					{
491						@Override
492						public void actionPerformed(ActionEvent ae)
493						{
494							save();
495							LogSettings.this.setVisible(false);
496							LogSettings.this.dispose();
497						}
498					});
499					JButton cancelButton = new JButton(jEdit.getProperty("common.cancel"));
500					cancelButton.addActionListener(new ActionListener()
501					{
502						@Override
503						public void actionPerformed(ActionEvent ae)
504						{
505							LogSettings.this.setVisible(false);
506							LogSettings.this.dispose();
507						}
508					});
509					buttonPanel.add(okButton);
510					buttonPanel.add(cancelButton);
511					addComponent(buttonPanel, GridBagConstraints.HORIZONTAL);
512				}
513				
514				@Override
515				protected void _save()
516				{
517					jEdit.setIntegerProperty("log-viewer.maxlines", ((SpinnerNumberModel)maxLines.getModel()).getNumber().intValue());
518					
519					showDebug = debug.isSelected();
520					jEdit.setBooleanProperty("log-viewer.message.debug", showDebug);
521					showMessage = message.isSelected();
522					jEdit.setBooleanProperty("log-viewer.message.message", showMessage);
523					showNotice = notice.isSelected();
524					jEdit.setBooleanProperty("log-viewer.message.notice", showNotice);
525					showWarning = warning.isSelected();
526					jEdit.setBooleanProperty("log-viewer.message.warning", showWarning);
527					showError = error.isSelected();
528					jEdit.setBooleanProperty("log-viewer.message.error", showError);
529					
530					jEdit.setColorProperty("log-viewer.message.debug.color", debugColor.getSelectedColor());	
531					jEdit.setColorProperty("log-viewer.message.message.color", messageColor.getSelectedColor());	
532					jEdit.setColorProperty("log-viewer.message.notice.color", noticeColor.getSelectedColor());	
533					jEdit.setColorProperty("log-viewer.message.warning.color", warningColor.getSelectedColor());	
534					jEdit.setColorProperty("log-viewer.message.error.color", errorColor.getSelectedColor());
535					
536					setFilter();
537				}
538			};
539			setContentPane(pane);
540			pane.init();
541			pack();
542			setLocationRelativeTo(LogViewer.this);
543			setVisible(true);
544		}
545		
546		private JSpinner maxLines;
547		private JCheckBox debug;
548		private JCheckBox message;
549		private JCheckBox notice;
550		private JCheckBox warning;
551		private JCheckBox error;
552		private ColorWellButton debugColor;
553		private ColorWellButton messageColor;
554		private ColorWellButton noticeColor;
555		private ColorWellButton warningColor;
556		private ColorWellButton errorColor;
557		
558	} //}}}
559}
560