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