Source code: org/gjt/sp/jedit/gui/StatusBar.java
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, 2002 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
24 package org.gjt.sp.jedit.gui;
25
26 //{{{ Imports
27 import javax.swing.border.*;
28 import javax.swing.text.Segment;
29 import javax.swing.*;
30 import java.awt.event.*;
31 import java.awt.font.*;
32 import java.awt.geom.*;
33 import java.awt.*;
34 import java.util.Calendar;
35 import java.util.Date;
36 import org.gjt.sp.jedit.io.*;
37 import org.gjt.sp.jedit.textarea.*;
38 import org.gjt.sp.jedit.*;
39 import 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,v 1.60 2003/11/30 04:22:52 spestov Exp $
56 * @author Slava Pestov
57 * @since jEdit 3.2pre2
58 */
59 public 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 Font font = UIManager.getFont("Label.font");
153 FontMetrics fm = getFontMetrics(font);
154 Dimension dim = null;
155
156 if (showCaretStatus)
157 {
158 panel.add(BorderLayout.WEST,caretStatus);
159
160 caretStatus.setFont(font);
161
162 dim = new Dimension(fm.stringWidth(caretTestStr),
163 fm.getHeight());
164 caretStatus.setPreferredSize(dim);
165 }
166 else
167 panel.remove(caretStatus);
168
169 box.removeAll();
170
171 if (showEncoding || showEditMode || showFoldMode)
172 box.add(mode);
173
174 if (showWrap)
175 {
176 dim = new Dimension(Math.max(
177 Math.max(fm.charWidth('-'),fm.charWidth('H')),
178 fm.charWidth('S')) + 1,fm.getHeight());
179 wrap.setPreferredSize(dim);
180 wrap.setMaximumSize(dim);
181 box.add(wrap);
182 }
183
184 if (showMultiSelect)
185 {
186 dim = new Dimension(
187 Math.max(fm.charWidth('-'),fm.charWidth('M')) + 1,
188 fm.getHeight());
189 multiSelect.setPreferredSize(dim);
190 multiSelect.setMaximumSize(dim);
191 box.add(multiSelect);
192 }
193
194 if (showRectSelect)
195 {
196 dim = new Dimension(
197 Math.max(fm.charWidth('-'),fm.charWidth('R')) + 1,
198 fm.getHeight());
199 rectSelect.setPreferredSize(dim);
200 rectSelect.setMaximumSize(dim);
201 box.add(rectSelect);
202 }
203
204 if (showOverwrite)
205 {
206 dim = new Dimension(
207 Math.max(fm.charWidth('-'),fm.charWidth('O')) + 1,
208 fm.getHeight());
209 overwrite.setPreferredSize(dim);
210 overwrite.setMaximumSize(dim);
211 box.add(overwrite);
212 }
213
214 if (showLineSeperator)
215 {
216 dim = new Dimension(Math.max(
217 Math.max(fm.charWidth('U'),
218 fm.charWidth('W')),
219 fm.charWidth('M')) + 1,
220 fm.getHeight());
221 lineSep.setPreferredSize(dim);
222 lineSep.setMaximumSize(dim);
223 box.add(lineSep);
224 }
225
226 if (showMemory)
227 box.add(new MemoryStatus());
228
229 if (showClock)
230 box.add(new Clock());
231
232 updateBufferStatus();
233 updateMiscStatus();
234 } //}}}
235
236 //{{{ addNotify() method
237 public void addNotify()
238 {
239 super.addNotify();
240 VFSManager.getIOThreadPool().addProgressListener(this);
241 } //}}}
242
243 //{{{ removeNotify() method
244 public void removeNotify()
245 {
246 super.removeNotify();
247 VFSManager.getIOThreadPool().removeProgressListener(this);
248 } //}}}
249
250 //{{{ WorkThreadListener implementation
251
252 //{{{ statusUpdate() method
253 public void statusUpdate(final WorkThreadPool threadPool, int threadIndex)
254 {
255 SwingUtilities.invokeLater(new Runnable()
256 {
257 public void run()
258 {
259 // don't obscure existing message
260 if(message != null && !"".equals(message.getText().trim())
261 && !currentMessageIsIO)
262 return;
263
264 int requestCount = threadPool.getRequestCount();
265 if(requestCount == 0)
266 {
267 setMessageAndClear(jEdit.getProperty(
268 "view.status.io.done"));
269 currentMessageIsIO = true;
270 }
271 else if(requestCount == 1)
272 {
273 setMessage(jEdit.getProperty(
274 "view.status.io-1"));
275 currentMessageIsIO = true;
276 }
277 else
278 {
279 Object[] args = { new Integer(requestCount) };
280 setMessage(jEdit.getProperty(
281 "view.status.io",args));
282 currentMessageIsIO = true;
283 }
284 }
285 });
286 } //}}}
287
288 //{{{ progressUpdate() method
289 public void progressUpdate(WorkThreadPool threadPool, int threadIndex)
290 {
291 } //}}}
292
293 //}}}
294
295 //{{{ setMessageAndClear() method
296 /**
297 * Show a message for a short period of time.
298 * @param message The message
299 * @since jEdit 3.2pre5
300 */
301 public void setMessageAndClear(String message)
302 {
303 setMessage(message);
304
305 tempTimer = new Timer(0,new ActionListener()
306 {
307 public void actionPerformed(ActionEvent evt)
308 {
309 // so if view is closed in the meantime...
310 if(isShowing())
311 setMessage(null);
312 }
313 });
314
315 tempTimer.setInitialDelay(10000);
316 tempTimer.setRepeats(false);
317 tempTimer.start();
318 } //}}}
319
320 //{{{ setMessage() method
321 /**
322 * Displays a status message.
323 */
324 public void setMessage(String message)
325 {
326 if(tempTimer != null)
327 {
328 tempTimer.stop();
329 tempTimer = null;
330 }
331
332 setMessageComponent(this.message);
333
334 if(message == null)
335 {
336 InputHandler inputHandler = view.getInputHandler();
337 /* if(inputHandler.isRepeatEnabled())
338 {
339 int repeatCount = inputHandler.getRepeatCount();
340
341 this.message.setText(jEdit.getProperty("view.status.repeat",
342 new Object[] { repeatCount == 1 ? "" : String.valueOf(repeatCount) }));
343 }
344 else */ if(view.getMacroRecorder() != null)
345 this.message.setText(jEdit.getProperty("view.status.recording"));
346 else
347 this.message.setText(" ");
348 }
349 else
350 this.message.setText(message);
351 } //}}}
352
353 //{{{ setMessageComponent() method
354 public void setMessageComponent(Component comp)
355 {
356 currentMessageIsIO = false;
357
358 if (comp == null || messageComp == comp)
359 {
360 return;
361 }
362
363 messageComp = comp;
364 panel.add(BorderLayout.CENTER, messageComp);
365 } //}}}
366
367 //{{{ updateCaretStatus() method
368 public void updateCaretStatus()
369 {
370 //if(!isShowing())
371 // return;
372
373 if (showCaretStatus)
374 {
375 Buffer buffer = view.getBuffer();
376
377 if(!buffer.isLoaded() ||
378 /* can happen when switching buffers sometimes */
379 buffer != view.getTextArea().getBuffer())
380 {
381 caretStatus.setText(" ");
382 return;
383 }
384
385 JEditTextArea textArea = view.getTextArea();
386
387 int currLine = textArea.getCaretLine();
388
389 // there must be a better way of fixing this...
390 // the problem is that this method can sometimes
391 // be called as a result of a text area scroll
392 // event, in which case the caret position has
393 // not been updated yet.
394 if(currLine >= buffer.getLineCount())
395 return; // hopefully another caret update will come?
396
397 int start = textArea.getLineStartOffset(currLine);
398 int dot = textArea.getCaretPosition() - start;
399
400 // see above
401 if(dot < 0)
402 return;
403
404 buffer.getText(start,dot,seg);
405 int virtualPosition = MiscUtilities.getVirtualWidth(seg,
406 buffer.getTabSize());
407
408 buf.setLength(0);
409 buf.append(Integer.toString(currLine + 1));
410 buf.append(',');
411 buf.append(Integer.toString(dot + 1));
412
413 if (virtualPosition != dot)
414 {
415 buf.append('-');
416 buf.append(Integer.toString(virtualPosition + 1));
417 }
418
419 buf.append(' ');
420
421 int firstLine = textArea.getFirstLine();
422 int visible = textArea.getVisibleLines();
423 int lineCount = textArea.getDisplayManager().getScrollLineCount();
424
425 if (visible >= lineCount)
426 {
427 buf.append("All");
428 }
429 else if (firstLine == 0)
430 {
431 buf.append("Top");
432 }
433 else if (firstLine + visible >= lineCount)
434 {
435 buf.append("Bot");
436 }
437 else
438 {
439 float percent = (float)firstLine / (float)lineCount
440 * 100.0f;
441 buf.append(Integer.toString((int)percent));
442 buf.append('%');
443 }
444
445 caretStatus.setText(buf.toString());
446 }
447 } //}}}
448
449 //{{{ updateBufferStatus() method
450 public void updateBufferStatus()
451 {
452 //if(!isShowing())
453 // return;
454
455 Buffer buffer = view.getBuffer();
456
457 if (showWrap)
458 {
459 String wrap = buffer.getStringProperty("wrap");
460 if(wrap.equals("none"))
461 this.wrap.setText("-");
462 else if(wrap.equals("hard"))
463 this.wrap.setText("H");
464 else if(wrap.equals("soft"))
465 this.wrap.setText("S");
466 }
467
468 if (showLineSeperator)
469 {
470 String lineSep = buffer.getStringProperty("lineSeparator");
471 if("\n".equals(lineSep))
472 this.lineSep.setText("U");
473 else if("\r\n".equals(lineSep))
474 this.lineSep.setText("W");
475 else if("\r".equals(lineSep))
476 this.lineSep.setText("M");
477 }
478
479 if (showEditMode || showFoldMode || showEncoding)
480 {
481 /* This doesn't look pretty and mode line should
482 * probably be split up into seperate
483 * components/strings
484 */
485 buf.setLength(0);
486
487 if (buffer.isLoaded())
488 {
489 if (showEditMode)
490 buf.append(buffer.getMode().getName());
491 if (showFoldMode)
492 {
493 if (showEditMode)
494 buf.append(",");
495 buf.append((String)view.getBuffer().getProperty("folding"));
496 }
497 if (showEncoding)
498 {
499 if (showEditMode || showFoldMode)
500 buf.append(",");
501 buf.append(buffer.getStringProperty("encoding"));
502 }
503 }
504
505 mode.setText("(" + buf.toString() + ")");
506 }
507 } //}}}
508
509 //{{{ updateMiscStatus() method
510 public void updateMiscStatus()
511 {
512 //if(!isShowing())
513 // return;
514
515 JEditTextArea textArea = view.getTextArea();
516
517 if (showMultiSelect)
518 multiSelect.setText(textArea.isMultipleSelectionEnabled()
519 ? "M" : "-");
520
521 if (showRectSelect)
522 rectSelect.setText(textArea.isRectangularSelectionEnabled()
523 ? "R" : "-");
524
525 if (showOverwrite)
526 overwrite.setText(textArea.isOverwriteEnabled()
527 ? "O" : "-");
528 } //}}}
529
530 //{{{ Private members
531 private View view;
532 private JPanel panel;
533 private Box box;
534 private ToolTipLabel caretStatus;
535 private Component messageComp;
536 private JLabel message;
537 private JLabel mode;
538 private JLabel wrap;
539 private JLabel multiSelect;
540 private JLabel rectSelect;
541 private JLabel overwrite;
542 private JLabel lineSep;
543 /* package-private for speed */ StringBuffer buf = new StringBuffer();
544 private Timer tempTimer;
545 private boolean currentMessageIsIO;
546
547 private Segment seg = new Segment();
548
549 private boolean showCaretStatus;
550 private boolean showEditMode;
551 private boolean showFoldMode;
552 private boolean showEncoding;
553 private boolean showWrap;
554 private boolean showMultiSelect;
555 private boolean showRectSelect;
556 private boolean showOverwrite;
557 private boolean showLineSeperator;
558 //}}}
559
560 static final String caretTestStr = "9999,999-999 99%";
561
562 //{{{ MouseHandler class
563 class MouseHandler extends MouseAdapter
564 {
565 public void mouseClicked(MouseEvent evt)
566 {
567 Buffer buffer = view.getBuffer();
568
569 Object source = evt.getSource();
570 if(source == caretStatus)
571 {
572 if(evt.getClickCount() == 2)
573 view.getTextArea().showGoToLineDialog();
574 }
575 else if(source == mode)
576 {
577 if(evt.getClickCount() == 2)
578 new BufferOptions(view,view.getBuffer());
579 }
580 else if(source == wrap)
581 buffer.toggleWordWrap(view);
582 else if(source == multiSelect)
583 view.getTextArea().toggleMultipleSelectionEnabled();
584 else if(source == rectSelect)
585 view.getTextArea().toggleRectangularSelectionEnabled();
586 else if(source == overwrite)
587 view.getTextArea().toggleOverwriteEnabled();
588 else if(source == lineSep)
589 buffer.toggleLineSeparator(view);
590 }
591 } //}}}
592
593 //{{{ ToolTipLabel class
594 class ToolTipLabel extends JLabel
595 {
596 //{{{ getToolTipLocation() method
597 public Point getToolTipLocation(MouseEvent event)
598 {
599 return new Point(event.getX(),-20);
600 } //}}}
601 } //}}}
602
603 //{{{ MemoryStatus class
604 class MemoryStatus extends JComponent implements ActionListener
605 {
606 //{{{ MemoryStatus constructor
607 public MemoryStatus()
608 {
609 Font font = UIManager.getFont("Label.font");
610 MemoryStatus.this.setFont(font);
611
612 FontRenderContext frc = new FontRenderContext(
613 null,false,false);
614 Rectangle2D bounds = font.getStringBounds(
615 memoryTestStr,frc);
616 Dimension dim = new Dimension((int)bounds.getWidth(),
617 (int)bounds.getHeight());
618 setPreferredSize(dim);
619 setMaximumSize(dim);
620 lm = font.getLineMetrics(memoryTestStr,frc);
621
622 setForeground(jEdit.getColorProperty("view.status.foreground"));
623 setBackground(jEdit.getColorProperty("view.status.background"));
624
625 progressForeground = jEdit.getColorProperty(
626 "view.status.memory.foreground");
627 progressBackground = jEdit.getColorProperty(
628 "view.status.memory.background");
629
630 addMouseListener(new MouseHandler());
631 } //}}}
632
633 //{{{ addNotify() method
634 public void addNotify()
635 {
636 super.addNotify();
637 timer = new Timer(2000,this);
638 timer.start();
639 ToolTipManager.sharedInstance().registerComponent(this);
640 } //}}}
641
642 //{{{ removeNotify() method
643 public void removeNotify()
644 {
645 timer.stop();
646 ToolTipManager.sharedInstance().unregisterComponent(this);
647 super.removeNotify();
648 } //}}}
649
650 //{{{ getToolTipText() method
651 public String getToolTipText()
652 {
653 Runtime runtime = Runtime.getRuntime();
654 int freeMemory = (int)(runtime.freeMemory() / 1024);
655 int totalMemory = (int)(runtime.totalMemory() / 1024);
656 int usedMemory = (totalMemory - freeMemory);
657 Integer[] args = { new Integer(usedMemory),
658 new Integer(totalMemory) };
659 return jEdit.getProperty("view.status.memory-tooltip",args);
660 } //}}}
661
662 //{{{ getToolTipLocation() method
663 public Point getToolTipLocation(MouseEvent event)
664 {
665 return new Point(event.getX(),-20);
666 } //}}}
667
668 //{{{ actionPerformed() method
669 public void actionPerformed(ActionEvent evt)
670 {
671 MemoryStatus.this.repaint();
672 } //}}}
673
674 //{{{ paintComponent() method
675 public void paintComponent(Graphics g)
676 {
677 Insets insets = new Insets(0,0,0,0);//MemoryStatus.this.getBorder().getBorderInsets(this);
678
679 Runtime runtime = Runtime.getRuntime();
680 int freeMemory = (int)(runtime.freeMemory() / 1024);
681 int totalMemory = (int)(runtime.totalMemory() / 1024);
682 int usedMemory = (totalMemory - freeMemory);
683
684 int width = MemoryStatus.this.getWidth()
685 - insets.left - insets.right;
686 int height = MemoryStatus.this.getHeight()
687 - insets.top - insets.bottom - 1;
688
689 float fraction = ((float)usedMemory) / totalMemory;
690
691 g.setColor(progressBackground);
692
693 g.fillRect(insets.left,insets.top,
694 (int)(width * fraction),
695 height);
696
697 String str = (usedMemory / 1024) + "/"
698 + (totalMemory / 1024) + "Mb";
699
700 FontRenderContext frc = new FontRenderContext(null,false,false);
701
702 Rectangle2D bounds = g.getFont().getStringBounds(str,frc);
703
704 Graphics g2 = g.create();
705 g2.setClip(insets.left,insets.top,
706 (int)(width * fraction),
707 height);
708
709 g2.setColor(progressForeground);
710
711 g2.drawString(str,
712 insets.left + (int)(width - bounds.getWidth()) / 2,
713 (int)(insets.top + lm.getAscent()));
714
715 g2.dispose();
716
717 g2 = g.create();
718
719 g2.setClip(insets.left + (int)(width * fraction),
720 insets.top,MemoryStatus.this.getWidth()
721 - insets.left - (int)(width * fraction),
722 height);
723
724 g2.setColor(MemoryStatus.this.getForeground());
725
726 g2.drawString(str,
727 insets.left + (int)(width - bounds.getWidth()) / 2,
728 (int)(insets.top + lm.getAscent()));
729
730 g2.dispose();
731 } //}}}
732
733 //{{{ Private members
734 private static final String memoryTestStr = "999/999Mb";
735
736 private LineMetrics lm;
737 private Color progressForeground;
738 private Color progressBackground;
739
740 private Timer timer;
741 //}}}
742
743 //{{{ MouseHandler class
744 class MouseHandler extends MouseAdapter
745 {
746 public void mousePressed(MouseEvent evt)
747 {
748 if(evt.getClickCount() == 2)
749 {
750 jEdit.showMemoryDialog(view);
751 repaint();
752 }
753 }
754 } //}}}
755 } //}}}
756
757 //{{{ Clock class
758 class Clock extends JLabel implements ActionListener
759 {
760 //{{{ Clock constructor
761 public Clock()
762 {
763 FontRenderContext frc = new FontRenderContext(
764 null,false,false);
765 Rectangle2D bounds = getFont()
766 .getStringBounds(clockTestStr,frc);
767 Dimension dim = new Dimension((int)bounds.getWidth(),
768 (int)bounds.getHeight());
769 setPreferredSize(dim);
770 setMaximumSize(dim);
771
772 setForeground(jEdit.getColorProperty("view.status.foreground"));
773 setBackground(jEdit.getColorProperty("view.status.background"));
774 } //}}}
775
776 //{{{ addNotify() method
777 public void addNotify()
778 {
779 super.addNotify();
780 update();
781
782 int millisecondsPerMinute = 1000 * 60;
783
784 timer = new Timer(millisecondsPerMinute,this);
785 timer.setInitialDelay((int)(
786 millisecondsPerMinute
787 - System.currentTimeMillis()
788 % millisecondsPerMinute) + 500);
789 timer.start();
790 ToolTipManager.sharedInstance().registerComponent(this);
791 } //}}}
792
793 //{{{ removeNotify() method
794 public void removeNotify()
795 {
796 timer.stop();
797 ToolTipManager.sharedInstance().unregisterComponent(this);
798 super.removeNotify();
799 } //}}}
800
801 //{{{ getToolTipText() method
802 public String getToolTipText()
803 {
804 return new Date().toString();
805 } //}}}
806
807 //{{{ getToolTipLocation() method
808 public Point getToolTipLocation(MouseEvent event)
809 {
810 return new Point(event.getX(),-20);
811 } //}}}
812
813 //{{{ actionPerformed() method
814 public void actionPerformed(ActionEvent evt)
815 {
816 update();
817 } //}}}
818
819 //{{{ Private members
820 private static final String clockTestStr = "04:20";
821
822 private Timer timer;
823
824 //{{{ update() method
825 private void update()
826 {
827 Calendar c = Calendar.getInstance();
828 buf.setLength(0);
829 int hour = c.get(Calendar.HOUR_OF_DAY);
830 if(hour < 10)
831 buf.append('0');
832 buf.append(hour);
833 buf.append(':');
834 int minute = c.get(Calendar.MINUTE);
835 if(minute < 10)
836 buf.append('0');
837 buf.append(minute);
838 setText(buf.toString());
839 } //}}}
840
841 //}}}
842 } //}}}
843 }