PageRenderTime 170ms CodeModel.GetById 126ms app.highlight 37ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-3-pre5/org/gjt/sp/jedit/gui/StatusBar.java

#
Java | 833 lines | 586 code | 126 blank | 121 comment | 95 complexity | ac18e0bbc18e83cd85079a1b5a35d461 MD5 | raw file
  1/*
  2 * StatusBar.java - The status bar displayed at the bottom of views
  3 * :tabSize=8:indentSize=8:noTabs=false:
  4 * :folding=explicit:collapseFolds=1:
  5 *
  6 * Copyright (C) 2001, 2004 Slava Pestov
  7 * Portions copyright (C) 2001 mike dillon
  8 *
  9 * This program is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU General Public License
 11 * as published by the Free Software Foundation; either version 2
 12 * of the License, or any later version.
 13 *
 14 * This program is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 * GNU General Public License for more details.
 18 *
 19 * You should have received a copy of the GNU General Public License
 20 * along with this program; if not, write to the Free Software
 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 22 */
 23
 24package org.gjt.sp.jedit.gui;
 25
 26//{{{ Imports
 27import javax.swing.border.*;
 28import javax.swing.text.Segment;
 29import javax.swing.*;
 30import java.awt.event.*;
 31import java.awt.font.*;
 32import java.awt.geom.*;
 33import java.awt.*;
 34import java.text.*;
 35import java.util.Date;
 36import org.gjt.sp.jedit.io.*;
 37import org.gjt.sp.jedit.textarea.*;
 38import org.gjt.sp.jedit.*;
 39import org.gjt.sp.util.*;
 40//}}}
 41
 42/**
 43 * The status bar used to display various information to the user.<p>
 44 *
 45 * Currently, it is used for the following:
 46 * <ul>
 47 * <li>Displaying caret position information
 48 * <li>Displaying {@link InputHandler#readNextChar(String,String)} prompts
 49 * <li>Displaying {@link #setMessage(String)} messages
 50 * <li>Displaying I/O progress
 51 * <li>Displaying various editor settings
 52 * <li>Displaying memory status
 53 * </ul>
 54 *
 55 * @version $Id: StatusBar.java 5485 2006-06-23 22:04:58Z kpouer $
 56 * @author Slava Pestov
 57 * @since jEdit 3.2pre2
 58 */
 59public class StatusBar extends JPanel implements WorkThreadProgressListener
 60{
 61	//{{{ StatusBar constructor
 62	public StatusBar(View view)
 63	{
 64		super(new BorderLayout());
 65		setBorder(new CompoundBorder(new EmptyBorder(4,0,0,
 66			(OperatingSystem.isMacOS() ? 18 : 0)),
 67			UIManager.getBorder("TextField.border")));
 68
 69		this.view = view;
 70
 71		panel = new JPanel(new BorderLayout());
 72		box = new Box(BoxLayout.X_AXIS);
 73		panel.add(BorderLayout.EAST,box);
 74		add(BorderLayout.CENTER,panel);
 75
 76		MouseHandler mouseHandler = new MouseHandler();
 77
 78		caretStatus = new ToolTipLabel();
 79		caretStatus.setToolTipText(jEdit.getProperty("view.status.caret-tooltip"));
 80		caretStatus.addMouseListener(mouseHandler);
 81
 82		message = new JLabel(" ");
 83		setMessageComponent(message);
 84
 85		mode = new ToolTipLabel();
 86		mode.setToolTipText(jEdit.getProperty("view.status.mode-tooltip"));
 87		mode.addMouseListener(mouseHandler);
 88
 89		wrap = new ToolTipLabel();
 90		wrap.setHorizontalAlignment(SwingConstants.CENTER);
 91		wrap.setToolTipText(jEdit.getProperty("view.status.wrap-tooltip"));
 92		wrap.addMouseListener(mouseHandler);
 93
 94		multiSelect = new ToolTipLabel();
 95		multiSelect.setHorizontalAlignment(SwingConstants.CENTER);
 96		multiSelect.setToolTipText(jEdit.getProperty("view.status.multi-tooltip"));
 97		multiSelect.addMouseListener(mouseHandler);
 98
 99		rectSelect = new ToolTipLabel();
100		rectSelect.setHorizontalAlignment(SwingConstants.CENTER);
101		rectSelect.setToolTipText(jEdit.getProperty("view.status.rect-tooltip"));
102		rectSelect.addMouseListener(mouseHandler);
103
104		overwrite = new ToolTipLabel();
105		overwrite.setHorizontalAlignment(SwingConstants.CENTER);
106		overwrite.setToolTipText(jEdit.getProperty("view.status.overwrite-tooltip"));
107		overwrite.addMouseListener(mouseHandler);
108
109		lineSep = new ToolTipLabel();
110		lineSep.setHorizontalAlignment(SwingConstants.CENTER);
111		lineSep.setToolTipText(jEdit.getProperty("view.status.linesep-tooltip"));
112		lineSep.addMouseListener(mouseHandler);
113	} //}}}
114
115	//{{{ propertiesChanged() method
116	public void propertiesChanged()
117	{
118		Color fg = jEdit.getColorProperty("view.status.foreground");
119		Color bg = jEdit.getColorProperty("view.status.background");
120
121		showCaretStatus = jEdit.getBooleanProperty("view.status.show-caret-status");
122		showEditMode = jEdit.getBooleanProperty("view.status.show-edit-mode");
123		showFoldMode = jEdit.getBooleanProperty("view.status.show-fold-mode");
124		showEncoding = jEdit.getBooleanProperty("view.status.show-encoding");
125		showWrap = jEdit.getBooleanProperty("view.status.show-wrap");
126		showMultiSelect = jEdit.getBooleanProperty("view.status.show-multi-select");
127		showRectSelect = jEdit.getBooleanProperty("view.status.show-rect-select");
128		showOverwrite = jEdit.getBooleanProperty("view.status.show-overwrite");
129		showLineSeperator = jEdit.getBooleanProperty("view.status.show-line-seperator");
130		boolean showMemory = jEdit.getBooleanProperty("view.status.show-memory");
131		boolean showClock = jEdit.getBooleanProperty("view.status.show-clock");
132
133		panel.setBackground(bg);
134		panel.setForeground(fg);
135		caretStatus.setBackground(bg);
136		caretStatus.setForeground(fg);
137		message.setBackground(bg);
138		message.setForeground(fg);
139		mode.setBackground(bg);
140		mode.setForeground(fg);
141		wrap.setBackground(bg);
142		wrap.setForeground(fg);
143		multiSelect.setBackground(bg);
144		multiSelect.setForeground(fg);
145		rectSelect.setBackground(bg);
146		rectSelect.setForeground(fg);
147		overwrite.setBackground(bg);
148		overwrite.setForeground(fg);
149		lineSep.setBackground(bg);
150		lineSep.setForeground(fg);
151
152		// retarded GTK look and feel!
153		Font font = new JLabel().getFont();
154		//UIManager.getFont("Label.font");
155		FontMetrics fm = getFontMetrics(font);
156		Dimension dim = null;
157
158		if (showCaretStatus)
159		{
160			panel.add(BorderLayout.WEST,caretStatus);
161
162			caretStatus.setFont(font);
163
164			dim = new Dimension(fm.stringWidth(caretTestStr),
165				fm.getHeight());
166                        caretStatus.setPreferredSize(dim);
167		}
168		else
169			panel.remove(caretStatus);
170
171		box.removeAll();
172
173		if (showEncoding || showEditMode || showFoldMode)
174			box.add(mode);
175
176		if (showWrap)
177		{
178			dim = new Dimension(Math.max(
179				Math.max(fm.charWidth('-'),fm.charWidth('H')),
180				fm.charWidth('S')) + 1,fm.getHeight());
181			wrap.setPreferredSize(dim);
182			wrap.setMaximumSize(dim);
183			box.add(wrap);
184		}
185
186		if (showMultiSelect)
187		{
188			dim = new Dimension(
189				Math.max(fm.charWidth('-'),fm.charWidth('M')) + 1,
190				fm.getHeight());
191			multiSelect.setPreferredSize(dim);
192			multiSelect.setMaximumSize(dim);
193			box.add(multiSelect);
194		}
195
196		if (showRectSelect)
197		{
198			dim = new Dimension(
199				Math.max(fm.charWidth('-'),fm.charWidth('R')) + 1,
200				fm.getHeight());
201			rectSelect.setPreferredSize(dim);
202			rectSelect.setMaximumSize(dim);
203			box.add(rectSelect);
204		}
205
206		if (showOverwrite)
207		{
208			dim = new Dimension(
209				Math.max(fm.charWidth('-'),fm.charWidth('O')) + 1,
210				fm.getHeight());
211			overwrite.setPreferredSize(dim);
212			overwrite.setMaximumSize(dim);
213			box.add(overwrite);
214		}
215
216		if (showLineSeperator)
217		{
218			dim = new Dimension(Math.max(
219				Math.max(fm.charWidth('U'),
220				fm.charWidth('W')),
221				fm.charWidth('M')) + 1,
222				fm.getHeight());
223			lineSep.setPreferredSize(dim);
224			lineSep.setMaximumSize(dim);
225			box.add(lineSep);
226		}
227
228		if (showMemory)
229			box.add(new MemoryStatus());
230
231		if (showClock)
232			box.add(new Clock());
233
234		updateBufferStatus();
235		updateMiscStatus();
236	} //}}}
237
238	//{{{ addNotify() method
239	public void addNotify()
240	{
241		super.addNotify();
242		VFSManager.getIOThreadPool().addProgressListener(this);
243	} //}}}
244
245	//{{{ removeNotify() method
246	public void removeNotify()
247	{
248		super.removeNotify();
249		VFSManager.getIOThreadPool().removeProgressListener(this);
250	} //}}}
251
252	//{{{ WorkThreadListener implementation
253
254	//{{{ statusUpdate() method
255	public void statusUpdate(final WorkThreadPool threadPool, int threadIndex)
256	{
257		SwingUtilities.invokeLater(new Runnable()
258		{
259			public void run()
260			{
261				// don't obscure existing message
262				if(message != null && !"".equals(message.getText().trim())
263					&& !currentMessageIsIO)
264					return;
265
266				int requestCount = threadPool.getRequestCount();
267				if(requestCount == 0)
268				{
269					setMessageAndClear(jEdit.getProperty(
270						"view.status.io.done"));
271					currentMessageIsIO = true;
272				}
273				else if(requestCount == 1)
274				{
275					setMessage(jEdit.getProperty(
276						"view.status.io-1"));
277					currentMessageIsIO = true;
278				}
279				else
280				{
281					Object[] args = { new Integer(requestCount) };
282					setMessage(jEdit.getProperty(
283						"view.status.io",args));
284					currentMessageIsIO = true;
285				}
286			}
287		});
288	} //}}}
289
290	//{{{ progressUpdate() method
291	public void progressUpdate(WorkThreadPool threadPool, int threadIndex)
292	{
293	} //}}}
294
295	//}}}
296
297	//{{{ setMessageAndClear() method
298	/**
299	 * Show a message for a short period of time.
300	 * @param message The message
301	 * @since jEdit 3.2pre5
302	 */
303	public void setMessageAndClear(String message)
304	{
305		setMessage(message);
306
307		tempTimer = new Timer(0,new ActionListener()
308		{
309			public void actionPerformed(ActionEvent evt)
310			{
311				// so if view is closed in the meantime...
312				if(isShowing())
313					setMessage(null);
314			}
315		});
316
317		tempTimer.setInitialDelay(10000);
318		tempTimer.setRepeats(false);
319		tempTimer.start();
320	} //}}}
321
322	//{{{ setMessage() method
323	/**
324	 * Displays a status message.
325	 */
326	public void setMessage(String message)
327	{
328		if(tempTimer != null)
329		{
330			tempTimer.stop();
331			tempTimer = null;
332		}
333
334		setMessageComponent(this.message);
335
336		if(message == null)
337		{
338			if(view.getMacroRecorder() != null)
339				this.message.setText(jEdit.getProperty("view.status.recording"));
340			else
341				this.message.setText(" ");
342		}
343		else
344			this.message.setText(message);
345	} //}}}
346
347	//{{{ setMessageComponent() method
348	public void setMessageComponent(Component comp)
349	{
350		currentMessageIsIO = false;
351
352		if (comp == null || messageComp == comp)
353		{
354			return;
355		}
356
357		messageComp = comp;
358		panel.add(BorderLayout.CENTER, messageComp);
359	} //}}}
360
361	//{{{ updateCaretStatus() method
362	public void updateCaretStatus()
363	{
364		//if(!isShowing())
365		//	return;
366
367		if (showCaretStatus)
368		{
369			Buffer buffer = view.getBuffer();
370
371			if(!buffer.isLoaded() ||
372				/* can happen when switching buffers sometimes */
373				buffer != view.getTextArea().getBuffer())
374			{
375				caretStatus.setText(" ");
376				return;
377			}
378
379			JEditTextArea textArea = view.getTextArea();
380
381			int currLine = textArea.getCaretLine();
382
383			// there must be a better way of fixing this...
384			// the problem is that this method can sometimes
385			// be called as a result of a text area scroll
386			// event, in which case the caret position has
387			// not been updated yet.
388			if(currLine >= buffer.getLineCount())
389				return; // hopefully another caret update will come?
390
391			int start = textArea.getLineStartOffset(currLine);
392			int dot = textArea.getCaretPosition() - start;
393
394			// see above
395			if(dot < 0)
396				return;
397
398			buffer.getText(start,dot,seg);
399			int virtualPosition = StandardUtilities.getVirtualWidth(seg,
400				buffer.getTabSize());
401
402			buf.setLength(0);
403			buf.append(Integer.toString(currLine + 1));
404			buf.append(',');
405			buf.append(Integer.toString(dot + 1));
406
407			if (virtualPosition != dot)
408			{
409				buf.append('-');
410				buf.append(Integer.toString(virtualPosition + 1));
411			}
412
413			buf.append(' ');
414
415			int firstLine = textArea.getFirstLine();
416			int visible = textArea.getVisibleLines();
417			int lineCount = textArea.getDisplayManager().getScrollLineCount();
418
419			if (visible >= lineCount)
420			{
421				buf.append("All");
422			}
423			else if (firstLine == 0)
424			{
425				buf.append("Top");
426			}
427			else if (firstLine + visible >= lineCount)
428			{
429				buf.append("Bot");
430			}
431			else
432			{
433				float percent = (float)firstLine / (float)lineCount
434					* 100.0f;
435				buf.append(Integer.toString((int)percent));
436				buf.append('%');
437			}
438
439			caretStatus.setText(buf.toString());
440		}
441	} //}}}
442
443	//{{{ updateBufferStatus() method
444	public void updateBufferStatus()
445	{
446		//if(!isShowing())
447		//	return;
448
449		Buffer buffer = view.getBuffer();
450
451		if (showWrap)
452		{
453			String wrap = buffer.getStringProperty("wrap");
454			if(wrap.equals("none"))
455				this.wrap.setText("-");
456			else if(wrap.equals("hard"))
457				this.wrap.setText("H");
458			else if(wrap.equals("soft"))
459				this.wrap.setText("S");
460		}
461
462		if (showLineSeperator)
463		{
464			String lineSep = buffer.getStringProperty("lineSeparator");
465			if("\n".equals(lineSep))
466				this.lineSep.setText("U");
467			else if("\r\n".equals(lineSep))
468				this.lineSep.setText("W");
469			else if("\r".equals(lineSep))
470				this.lineSep.setText("M");
471		}
472
473		if (showEditMode || showFoldMode || showEncoding)
474		{
475			/* This doesn't look pretty and mode line should
476			 * probably be split up into seperate
477			 * components/strings
478			 */
479			buf.setLength(0);
480
481			if (buffer.isLoaded())
482			{
483				if (showEditMode)
484					buf.append(buffer.getMode().getName());
485				if (showFoldMode)
486				{
487					if (showEditMode)
488						buf.append(",");
489					buf.append((String)view.getBuffer().getProperty("folding"));
490				}
491				if (showEncoding)
492				{
493					if (showEditMode || showFoldMode)
494						buf.append(",");
495					buf.append(buffer.getStringProperty("encoding"));
496				}
497			}
498
499			mode.setText("(" + buf.toString() + ")");
500		}
501	} //}}}
502
503	//{{{ updateMiscStatus() method
504	public void updateMiscStatus()
505	{
506		//if(!isShowing())
507		//	return;
508
509		JEditTextArea textArea = view.getTextArea();
510
511		if (showMultiSelect)
512			multiSelect.setText(textArea.isMultipleSelectionEnabled()
513				? "M" : "-");
514
515		if (showRectSelect)
516			rectSelect.setText(textArea.isRectangularSelectionEnabled()
517				? "R" : "-");
518
519		if (showOverwrite)
520			overwrite.setText(textArea.isOverwriteEnabled()
521				? "O" : "-");
522	} //}}}
523
524	//{{{ Private members
525	private View view;
526	private JPanel panel;
527	private Box box;
528	private ToolTipLabel caretStatus;
529	private Component messageComp;
530	private JLabel message;
531	private JLabel mode;
532	private JLabel wrap;
533	private JLabel multiSelect;
534	private JLabel rectSelect;
535	private JLabel overwrite;
536	private JLabel lineSep;
537	/* package-private for speed */ StringBuffer buf = new StringBuffer();
538	private Timer tempTimer;
539	private boolean currentMessageIsIO;
540
541	private Segment seg = new Segment();
542
543	private boolean showCaretStatus;
544	private boolean showEditMode;
545	private boolean showFoldMode;
546	private boolean showEncoding;
547	private boolean showWrap;
548	private boolean showMultiSelect;
549	private boolean showRectSelect;
550	private boolean showOverwrite;
551	private boolean showLineSeperator;
552	//}}}
553
554	static final String caretTestStr = "9999,999-999 99%";
555
556	//{{{ MouseHandler class
557	class MouseHandler extends MouseAdapter
558	{
559		public void mouseClicked(MouseEvent evt)
560		{
561			Buffer buffer = view.getBuffer();
562
563			Object source = evt.getSource();
564			if(source == caretStatus)
565			{
566				if(evt.getClickCount() == 2)
567					view.getTextArea().showGoToLineDialog();
568			}
569			else if(source == mode)
570			{
571				if(evt.getClickCount() == 2)
572					new BufferOptions(view,view.getBuffer());
573			}
574			else if(source == wrap)
575				buffer.toggleWordWrap(view);
576			else if(source == multiSelect)
577				view.getTextArea().toggleMultipleSelectionEnabled();
578			else if(source == rectSelect)
579				view.getTextArea().toggleRectangularSelectionEnabled();
580			else if(source == overwrite)
581				view.getTextArea().toggleOverwriteEnabled();
582			else if(source == lineSep)
583				buffer.toggleLineSeparator(view);
584		}
585	} //}}}
586
587	//{{{ ToolTipLabel class
588	class ToolTipLabel extends JLabel
589	{
590		//{{{ getToolTipLocation() method
591		public Point getToolTipLocation(MouseEvent event)
592		{
593			return new Point(event.getX(),-20);
594		} //}}}
595	} //}}}
596
597	//{{{ MemoryStatus class
598	class MemoryStatus extends JComponent implements ActionListener
599	{
600		//{{{ MemoryStatus constructor
601		public MemoryStatus()
602		{
603			// fucking GTK look and feel
604			Font font = new JLabel().getFont();
605			//Font font = UIManager.getFont("Label.font");
606			MemoryStatus.this.setFont(font);
607
608			FontRenderContext frc = new FontRenderContext(
609				null,false,false);
610			Rectangle2D bounds = font.getStringBounds(		
611				memoryTestStr,frc);
612			Dimension dim = new Dimension((int)bounds.getWidth(),
613				(int)bounds.getHeight());
614			setPreferredSize(dim);
615			setMaximumSize(dim);
616			lm = font.getLineMetrics(memoryTestStr,frc);
617
618			setForeground(jEdit.getColorProperty("view.status.foreground"));
619			setBackground(jEdit.getColorProperty("view.status.background"));
620
621			progressForeground = jEdit.getColorProperty(
622				"view.status.memory.foreground");
623			progressBackground = jEdit.getColorProperty(
624				"view.status.memory.background");
625
626			addMouseListener(new MouseHandler());
627		} //}}}
628
629		//{{{ addNotify() method
630		public void addNotify()
631		{
632			super.addNotify();
633			timer = new Timer(2000,this);
634			timer.start();
635			ToolTipManager.sharedInstance().registerComponent(this);
636		} //}}}
637
638		//{{{ removeNotify() method
639		public void removeNotify()
640		{
641			timer.stop();
642			ToolTipManager.sharedInstance().unregisterComponent(this);
643			super.removeNotify();
644		} //}}}
645
646		//{{{ getToolTipText() method
647		public String getToolTipText()
648		{
649			Runtime runtime = Runtime.getRuntime();
650			int freeMemory = (int)(runtime.freeMemory() / 1024);
651			int totalMemory = (int)(runtime.maxMemory() / 1024);
652			int usedMemory = (totalMemory - freeMemory);
653			Integer[] args = { new Integer(usedMemory),
654				new Integer(totalMemory) };
655			return jEdit.getProperty("view.status.memory-tooltip",args);
656		} //}}}
657
658		//{{{ getToolTipLocation() method
659		public Point getToolTipLocation(MouseEvent event)
660		{
661			return new Point(event.getX(),-20);
662		} //}}}
663
664		//{{{ actionPerformed() method
665		public void actionPerformed(ActionEvent evt)
666		{
667			MemoryStatus.this.repaint();
668		} //}}}
669
670		//{{{ paintComponent() method
671		public void paintComponent(Graphics g)
672		{
673			Insets insets = new Insets(0,0,0,0);//MemoryStatus.this.getBorder().getBorderInsets(this);
674
675			Runtime runtime = Runtime.getRuntime();
676			int freeMemory = (int)(runtime.freeMemory() / 1024);
677			int totalMemory = (int)(runtime.totalMemory() / 1024);
678			int usedMemory = (totalMemory - freeMemory);
679
680			int width = MemoryStatus.this.getWidth()
681				- insets.left - insets.right;
682			int height = MemoryStatus.this.getHeight()
683				- insets.top - insets.bottom - 1;
684
685			float fraction = ((float)usedMemory) / totalMemory;
686
687			g.setColor(progressBackground);
688
689			g.fillRect(insets.left,insets.top,
690				(int)(width * fraction),
691				height);
692
693			String str = (usedMemory / 1024) + "/"
694				+ (totalMemory / 1024) + "Mb";
695
696			FontRenderContext frc = new FontRenderContext(null,false,false);
697
698			Rectangle2D bounds = g.getFont().getStringBounds(str,frc);
699		
700			Graphics g2 = g.create();
701			g2.setClip(insets.left,insets.top,
702				(int)(width * fraction),
703				height);
704
705			g2.setColor(progressForeground);
706
707			g2.drawString(str,
708				insets.left + (int)(width - bounds.getWidth()) / 2,
709				(int)(insets.top + lm.getAscent()));
710
711			g2.dispose();
712
713			g2 = g.create();
714
715			g2.setClip(insets.left + (int)(width * fraction),
716				insets.top,MemoryStatus.this.getWidth()
717				- insets.left - (int)(width * fraction),
718				height);
719
720			g2.setColor(MemoryStatus.this.getForeground());
721
722			g2.drawString(str,
723				insets.left + (int)(width - bounds.getWidth()) / 2,
724				(int)(insets.top + lm.getAscent()));
725
726			g2.dispose();
727		} //}}}
728
729		//{{{ Private members
730		private static final String memoryTestStr = "999/999Mb";
731
732		private LineMetrics lm;
733		private Color progressForeground;
734		private Color progressBackground;
735
736		private Timer timer;
737		//}}}
738
739		//{{{ MouseHandler class
740		class MouseHandler extends MouseAdapter
741		{
742			public void mousePressed(MouseEvent evt)
743			{
744				if(evt.getClickCount() == 2)
745				{
746					jEdit.showMemoryDialog(view);
747					repaint();
748				}
749			}
750		} //}}}
751	} //}}}
752
753	//{{{ Clock class
754	class Clock extends JLabel implements ActionListener
755	{
756		//{{{ Clock constructor
757		public Clock()
758		{
759			/* FontRenderContext frc = new FontRenderContext(
760				null,false,false);
761			Rectangle2D bounds = getFont()
762				.getStringBounds(getTime(),frc);
763			Dimension dim = new Dimension((int)bounds.getWidth(),
764				(int)bounds.getHeight());
765			setPreferredSize(dim);
766			setMaximumSize(dim); */
767
768			setForeground(jEdit.getColorProperty("view.status.foreground"));
769			setBackground(jEdit.getColorProperty("view.status.background"));
770		} //}}}
771
772		//{{{ addNotify() method
773		public void addNotify()
774		{
775			super.addNotify();
776			update();
777
778			int millisecondsPerMinute = 1000 * 60;
779
780			timer = new Timer(millisecondsPerMinute,this);
781			timer.setInitialDelay((int)(
782				millisecondsPerMinute
783				- System.currentTimeMillis()
784				% millisecondsPerMinute) + 500);
785			timer.start();
786			ToolTipManager.sharedInstance().registerComponent(this);
787		} //}}}
788
789		//{{{ removeNotify() method
790		public void removeNotify()
791		{
792			timer.stop();
793			ToolTipManager.sharedInstance().unregisterComponent(this);
794			super.removeNotify();
795		} //}}}
796
797		//{{{ getToolTipText() method
798		public String getToolTipText()
799		{
800			return new Date().toString();
801		} //}}}
802
803		//{{{ getToolTipLocation() method
804		public Point getToolTipLocation(MouseEvent event)
805		{
806			return new Point(event.getX(),-20);
807		} //}}}
808
809		//{{{ actionPerformed() method
810		public void actionPerformed(ActionEvent evt)
811		{
812			update();
813		} //}}}
814
815		//{{{ Private members
816		private Timer timer;
817
818		//{{{ getTime() method
819		private String getTime()
820		{
821			return DateFormat.getTimeInstance(
822				DateFormat.SHORT).format(new Date());
823		} //}}}
824
825		//{{{ update() method
826		private void update()
827		{
828			setText(getTime());
829		} //}}}
830
831		//}}}
832	} //}}}
833}