source: trunk/src/org/expeditee/gui/FrameGraphics.java@ 48

Last change on this file since 48 was 48, checked in by ra33, 16 years ago

Made both types of messages (normal and overwrite mode) output the numbered prefix

File size: 21.7 KB
Line 
1package org.expeditee.gui;
2
3import java.awt.Color;
4import java.awt.Component;
5import java.awt.Container;
6import java.awt.Dimension;
7import java.awt.Font;
8import java.awt.Graphics;
9import java.awt.Graphics2D;
10import java.awt.GraphicsEnvironment;
11import java.awt.Point;
12import java.awt.RenderingHints;
13import java.awt.image.VolatileImage;
14import java.util.LinkedList;
15import java.util.List;
16
17import javax.swing.JPopupMenu;
18import javax.swing.SwingUtilities;
19
20import org.expeditee.actions.Misc;
21import org.expeditee.items.Dot;
22import org.expeditee.items.InteractiveWidget;
23import org.expeditee.items.Item;
24import org.expeditee.items.Line;
25import org.expeditee.items.Picture;
26import org.expeditee.items.Text;
27import org.expeditee.items.WidgetEdge;
28
29public class FrameGraphics {
30 public static final int MESSAGE_BUFFER_HEIGHT = 100;
31
32 private static final int MESSAGE_LINK_Y_OFFSET = 100;
33
34 private static final int MESSAGE_LINK_X = 50;
35
36 // the graphics used to paint with
37 private static Graphics2D _DisplayGraphics;
38
39 // the maximum size that can be used to paint on
40 private static Dimension _MaxSize;
41
42 // messages shown in the message window
43 public static Text[] Messages = new Text[4];
44
45 // buffer of the message window
46 private static VolatileImage _MessageBuffer = null;
47
48 // font used for the messages
49 private static Font _MessageFont = Font.decode("Serif-Plain-16");
50
51 // the number of messages currently shown (used for scrolling up)
52 private static int _MessageCount = 0;
53
54 // modes
55 public static final int MODE_NORMAL = 0;
56
57 public static final int MODE_AUDIENCE = 1;
58
59 public static final int MODE_XRAY = 2;
60
61 private static int _Mode = MODE_NORMAL;
62
63 // if true, error messages are not shown to the user
64 private static boolean _SupressErrors = false;
65
66 // The link to the message frameset
67 public static Text MessageLink = new Text(-2, "Messages");
68
69 // Date\time formatter for timestamping the messages
70 /*
71 * private static SimpleDateFormat _formatter = new SimpleDateFormat( "
72 * [ddMMMyyyy:HHmm]");
73 */
74
75 // creator for creating the message frames
76 private static FrameCreator _creator;
77
78 /**
79 * Returns the Graphics2D object currently being used to draw with, this may
80 * be null if no Graphics2D has been assigned yet.
81 *
82 * @return the Graphics2D object being used to draw, or null.
83 */
84 public static Graphics2D getGraphics() {
85 return _DisplayGraphics;
86 }
87
88 /**
89 * If Audience Mode is on this method will toggle it to be off, or
90 * vice-versa. This results in the Frame being re-parsed and repainted.
91 */
92 public static void ToggleAudienceMode() {
93 if (_Mode == MODE_AUDIENCE)
94 _Mode = MODE_NORMAL;
95 else
96 _Mode = MODE_AUDIENCE;
97
98 FrameUtils.Parse(DisplayIO.getCurrentFrame());
99 DisplayIO.UpdateTitle();
100 Repaint();
101 }
102
103 /**
104 * If X-Ray Mode is on this method will toggle it to be off, or vice-versa.
105 * This results in the Frame being re-parsed and repainted.
106 */
107 public static void ToggleXRayMode() {
108 if (_Mode == MODE_XRAY)
109 _Mode = MODE_NORMAL;
110 else
111 _Mode = MODE_XRAY;
112
113 FrameUtils.Parse(DisplayIO.getCurrentFrame());
114 Repaint();
115 }
116
117 /**
118 * @return True if Audience Mode is currently on, False otherwise.
119 */
120 public static boolean isAudienceMode() {
121 return _Mode == MODE_AUDIENCE;
122 }
123
124 /**
125 * @return True if X-Ray Mode is currently on, False otherwise.
126 */
127 public static boolean isXRayMode() {
128 return _Mode == MODE_XRAY;
129 }
130
131 public static void setMaxSize(Dimension max) {
132 if (_MaxSize == null)
133 _MaxSize = max;
134
135 // Mike assumes this is the height of the Message window?
136 _MaxSize.setSize(max.width, max.height - MESSAGE_BUFFER_HEIGHT);
137 if (DisplayIO.getCurrentFrame() != null) {
138 DisplayIO.getCurrentFrame().setBuffer(null);
139 DisplayIO.getCurrentFrame().setMaxSize(max);
140 }
141
142 _MessageBuffer = null;
143
144 for (int i = 0; i < Messages.length; i++) {
145 if (Messages[i] != null) {
146 Messages[i].setOffset(0, -_MaxSize.height);
147 Messages[i].setMaxSize(_MaxSize);
148 }
149 }
150
151 MessageLink.setOffset(0, -_MaxSize.height);
152 MessageLink.setMaxSize(_MaxSize);
153 MessageLink.setPosition(_MaxSize.width - MESSAGE_LINK_Y_OFFSET,
154 MESSAGE_LINK_X);
155
156 Repaint();
157 }
158
159 public static Dimension getMaxSize() {
160 return _MaxSize;
161 }
162
163 public static Dimension getMaxFrameSize() {
164 if (DisplayIO.isTwinFramesOn()) {
165 return new Dimension((_MaxSize.width / 2), _MaxSize.height);
166 } else
167 return _MaxSize;
168 }
169
170 /**
171 * Sets the Graphics2D object that should be used for all painting tasks.
172 * Note: Actual painting is done by using g.create() to create temporary
173 * instances that are then disposed of using g.dispose().
174 *
175 * @param g
176 * The Graphics2D object to use for all painting
177 */
178 public static void setDisplayGraphics(Graphics2D g) {
179 _DisplayGraphics = g;
180 }
181
182 /*
183 * Displays the given Item on the screen
184 */
185 private static void PaintItem(Graphics2D g, Item i) {
186 if (i == null || g == null)
187 return;
188
189 // do not paint annotation items in audience mode
190 if (g != null
191 && (!isAudienceMode()
192 || (isAudienceMode() && !i.isAnnotation()) || i == FrameUtils.LastEdited)) {
193
194 Graphics2D tg = (Graphics2D) g.create();
195 i.paint(tg);
196 tg.dispose();
197 }
198 }
199
200 public static void AddAllOverlayItems(List<Item> items, Frame overlay,
201 List<Frame> seenOverlays) {
202 if (seenOverlays.contains(overlay))
203 return;
204
205 seenOverlays.add(overlay);
206
207 for (Overlay o : overlay.getOverlays())
208 AddAllOverlayItems(items, o.Frame, seenOverlays);
209
210 items.addAll(overlay.getItems());
211 }
212
213 /**
214 * Recursive function similar to AddAllOverlayItems.
215 *
216 * @param widgets
217 * The collection the widgets will be added to
218 * @param overlay
219 * An "overlay" frame - this intially will be the parent frame
220 * @param seenOverlays
221 * Used for state in the recursion stack. Pass as an empty
222 * (non-null) list.
223 */
224 public static void AddAllOverlayWidgets(List<InteractiveWidget> widgets,
225 Frame overlay, List<Frame> seenOverlays) {
226 if (seenOverlays.contains(overlay))
227 return;
228
229 seenOverlays.add(overlay);
230
231 for (Overlay o : overlay.getOverlays())
232 AddAllOverlayWidgets(widgets, o.Frame, seenOverlays);
233
234 widgets.addAll(overlay.getInteractiveWidgets());
235 }
236
237 private static VolatileImage Paint(Frame toPaint) {
238 return Paint(toPaint, true);
239 }
240
241 private static VolatileImage Paint(Frame toPaint, boolean paintOverlay) {
242 if (toPaint == null)
243 return null;
244
245 // the buffer is not valid, so it must be recreated
246 if (!toPaint.isBufferValid()) {
247 VolatileImage buffer = toPaint.getBuffer();
248 if (buffer == null) {
249 GraphicsEnvironment ge = GraphicsEnvironment
250 .getLocalGraphicsEnvironment();
251 buffer = ge.getDefaultScreenDevice().getDefaultConfiguration()
252 .createCompatibleVolatileImage(_MaxSize.width,
253 _MaxSize.height);
254 toPaint.setBuffer(buffer);
255 }
256
257 Graphics2D bg = (Graphics2D) buffer.getGraphics();
258
259 // Nicer looking lines, but may be too jerky while
260 // rubber-banding on older machines
261 if (UserSettings.AntiAlias)
262 ((Graphics2D) bg).setRenderingHint(
263 RenderingHints.KEY_ANTIALIASING,
264 RenderingHints.VALUE_ANTIALIAS_ON);
265
266 bg.setColor(toPaint.getPaintBackgroundColor());
267 bg.fillRect(0, 0, _MaxSize.width, _MaxSize.height);
268
269 List<Item> paintItems = new LinkedList<Item>();
270 List<InteractiveWidget> paintWidgets;
271
272 if (paintOverlay) {
273
274 AddAllOverlayItems(paintItems, toPaint, new LinkedList<Frame>());
275
276 paintWidgets = new LinkedList<InteractiveWidget>();
277 AddAllOverlayWidgets(paintWidgets, toPaint,
278 new LinkedList<Frame>());
279
280 } else {
281 paintItems.addAll(toPaint.getItems());
282 paintWidgets = toPaint.getInteractiveWidgets();
283 }
284
285 // FIRST: Paint widgets swing gui (not expeditee gui) .
286 // Note that these are the ancored widgets
287 for (InteractiveWidget iw : paintWidgets) {
288 iw.paint(bg);
289 }
290
291 PaintPictures(bg, paintItems);
292
293 if (toPaint == DisplayIO.getCurrentFrame())
294 PaintPictures(bg, Frame.FreeItems);
295
296 PaintNonLinesNonPicture(bg, paintItems);
297 PaintLines(bg, paintItems);
298
299 if (toPaint == DisplayIO.getCurrentFrame())
300 PaintNonLinesNonPicture(bg, Frame.FreeItems);
301
302 // toPaint.setBufferValid(true);
303
304 if (DisplayIO.isTwinFramesOn()) {
305 List<Item> lines = new LinkedList<Item>();
306 for (Item i : Frame.FreeItems) {
307 if (i instanceof Line) {
308 Line line = (Line) i;
309
310 if (toPaint != DisplayIO.getCurrentFrame()) {
311 if (line.getEndItem().isFloating()
312 ^ line.getStartItem().isFloating()) {
313 lines.add(TransposeLine(line,
314 line.getEndItem(), toPaint, DisplayIO
315 .getRealMouseX(), -DisplayIO
316 .getMiddle()));
317 lines.add(TransposeLine(line, line
318 .getStartItem(), toPaint, DisplayIO
319 .getRealMouseX(), -DisplayIO
320 .getMiddle()));
321 }
322 } else {
323 if (line.getEndItem().isFloating()
324 ^ line.getStartItem().isFloating()) {
325 Line l = TransposeLine(line, line.getEndItem(),
326 toPaint, 0, 0);
327 if (l == null)
328 l = TransposeLine(line,
329 line.getStartItem(), toPaint, 0, 0);
330 if (l == null)
331 l = line;
332 lines.add(l);
333 } else
334 lines.add(line);
335 }
336 }
337 }
338 PaintLines(bg, lines);
339 } else {
340 // PaintPictures(bg, Frame.FreeItems);
341 // PaintNonLinesNonPicture(bg, Frame.FreeItems);
342 PaintLines(bg, Frame.FreeItems);
343 }
344
345 if (paintOverlay) {
346 PaintItem(bg, toPaint.getFrameNameItem());
347 }
348
349 // BROOK: Ensure popups are repainted
350 if (Browser._theBrowser != null)
351 repaintPopups(Browser._theBrowser.getLayeredPane(), bg);
352
353 bg.dispose();
354 }
355
356 return toPaint.getBuffer();
357 }
358
359 // creates a new line so that lines are shown correctly when spanning
360 // across frames in TwinFrames mode
361 private static Line TransposeLine(Line line, Item d, Frame toPaint,
362 int base, int adj) {
363 Line nl = null;
364
365 if (toPaint != DisplayIO.getCurrentFrame() && d.getParent() == null
366 && line.getOppositeEnd(d).getParent() == toPaint) {
367 nl = line.copy();
368 if (d == line.getStartItem())
369 d = nl.getStartItem();
370 else
371 d = nl.getEndItem();
372
373 if (DisplayIO.FrameOnSide(toPaint) == 0)
374 d.setX(base);
375 else
376 d.setX(base + adj);
377
378 } else if (toPaint == DisplayIO.getCurrentFrame()
379 && d.getParent() == null
380 && line.getOppositeEnd(d).getParent() != toPaint) {
381 nl = line.copy();
382
383 if (d == line.getStartItem())
384 d = nl.getEndItem();
385 else
386 d = nl.getStartItem();
387
388 if (DisplayIO.FrameOnSide(toPaint) == 1)
389 d.setX(d.getX() - DisplayIO.getMiddle());
390 else
391 d.setX(d.getX() + DisplayIO.getMiddle());
392 }
393
394 return nl;
395 }
396
397 private static void Paint(VolatileImage left, VolatileImage right,
398 Color background) {
399 if (_MessageBuffer == null) {
400 GraphicsEnvironment ge = GraphicsEnvironment
401 .getLocalGraphicsEnvironment();
402 _MessageBuffer = ge.getDefaultScreenDevice()
403 .getDefaultConfiguration().createCompatibleVolatileImage(
404 _MaxSize.width, MESSAGE_BUFFER_HEIGHT);
405 }
406
407 paintMessage(_MessageBuffer.createGraphics(), background);
408 Graphics g = _DisplayGraphics.create();
409
410 // if TwinFrames mode is on, then clipping etc has to be set
411 if (DisplayIO.isTwinFramesOn()) {
412 // draw the two lines down the middle of the window
413 if (left != null)
414 left.getGraphics().drawLine(DisplayIO.getMiddle() - 2, 0,
415 DisplayIO.getMiddle() - 2, _MaxSize.height);
416
417 if (right != null)
418 right.getGraphics().drawLine(0, 0, 0, _MaxSize.height);
419
420 // set the clipping area
421 ((Graphics2D) g).setClip(0, 0, DisplayIO.getMiddle() - 1,
422 _MaxSize.height);
423 g.drawImage(left, 0, 0, DisplayIO.DEFAULT_BACKGROUND, null);
424 ((Graphics2D) g).setClip(null);
425 g.drawImage(right, DisplayIO.getMiddle() + 1, 0,
426 DisplayIO.DEFAULT_BACKGROUND, null);
427
428 // otherwise, just draw whichever side is active
429 } else {
430 if (DisplayIO.getCurrentSide() == 0)
431 g.drawImage(left, 0, 0, DisplayIO.DEFAULT_BACKGROUND, null);
432 else
433 g.drawImage(right, 0, 0, DisplayIO.DEFAULT_BACKGROUND, null);
434 }
435 // draw the message area
436 g.drawImage(_MessageBuffer, 0, _MaxSize.height, null);
437 g.dispose();
438
439 }
440
441 /**
442 * Paints the message area
443 * @param g
444 * @param background
445 */
446 private static void paintMessage(Graphics2D g, Color background) {
447 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
448 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
449 g.setColor(background);
450 g.fillRect(0, 0, _MaxSize.width, MESSAGE_BUFFER_HEIGHT);
451 g.setFont(_MessageFont);
452 g.setColor(Color.BLACK);
453 g.drawLine(0, 0, _MaxSize.width, 0);
454 for (Text t : Messages)
455 PaintItem(g, t);
456 if (MessageLink.getLink() != null)
457 PaintItem(g, MessageLink);
458 g.dispose();
459 }
460
461 public static void Clear() {
462 Graphics g = _DisplayGraphics.create();
463 g.setColor(Color.WHITE);
464 g.fillRect(0, 0, _MaxSize.width, _MaxSize.height);
465 g.dispose();
466 }
467
468 /**
469 * Called to refresh the display screen.
470 *
471 */
472 public static void Repaint() {
473 if (_DisplayGraphics == null)
474 return;
475
476 if (UserSettings.Threading) {
477 if (painter == null) {
478 painter = new FrameGraphics().new Repainter();
479
480 painter.setDaemon(true);
481 painter.setPriority(Thread.MIN_PRIORITY);
482
483 painter.start();
484 } else
485 painter.run();
486 } else {
487 Frame[] toPaint = DisplayIO.getFrames();
488
489 if (toPaint != null) {
490 VolatileImage left = Paint(toPaint[0]);
491 VolatileImage right = Paint(toPaint[1]);
492 Paint(left, right, DisplayIO.DEFAULT_BACKGROUND);
493 }
494 }
495 }
496
497 private static Repainter painter = null;
498
499 private static void PaintNonLinesNonPicture(Graphics2D g, List<Item> toPaint) {
500 for (Item i : toPaint)
501 if (!(i instanceof Line) && !(i instanceof Picture))
502 PaintItem(g, i);
503 }
504
505 private static void PaintLines(Graphics2D g, List<Item> toPaint) {
506 for (Item i : toPaint)
507 if (i instanceof Line)
508 PaintItem(g, i);
509 }
510
511 private static void PaintPictures(Graphics2D g, List<Item> toPaint) {
512 for (Item i : toPaint) {
513 if (i instanceof Picture)
514 PaintItem(g, i);
515 else if (i instanceof Dot)
516 ((Dot) i).paintFill(g);
517 }
518 }
519
520 /**
521 * Highlights an item on the screen Note: All graphics are handled by the
522 * Item itself.
523 *
524 * @param i
525 * The Item to highlight.
526 * @param val
527 * True if the highlighting is being shown, false if it is being
528 * erased.
529 */
530 public static void Highlight(Item i) {
531 if ((i instanceof Line)) {
532 // Check if within 20% of the end of the line
533 Line l = (Line) i;
534 Item toDisconnect = l.getEndPointToDisconnect(
535 FrameMouseActions.MouseX, FrameMouseActions.MouseY);
536
537 // Brook: Widget Edges do not have such a context
538 if (toDisconnect != null && !(i instanceof WidgetEdge)) {
539 Item.SelectedMode newMode = toDisconnect.getSelectedMode();
540 if (Frame.itemAttachedToCursor())
541 newMode = Item.SelectedMode.Normal;
542 // unhighlight all the other dots
543 for (Item conn : toDisconnect.getAllConnected()) {
544 conn.setSelectedMode(Item.SelectedMode.None);
545 }
546 l.setSelectedMode(newMode);
547 // highlight the dot that will be in disconnect mode
548 toDisconnect.setSelectedMode(newMode);
549 } else {
550 List<Item> connected = i.getAllConnected();
551 for (Item conn : connected) {
552 conn.setSelectedMode(Item.SelectedMode.Connected);
553 }
554 }
555 } else {
556 i.setSelectedMode(Item.SelectedMode.Normal);
557 }
558
559 Repaint();
560 }
561
562 public static void ChangeSelectionMode(Item item, Item.SelectedMode newMode) {
563 if (item == null)
564 return;
565
566 for(Item i: item.getAllConnected())
567 i.setSelectedMode(newMode);
568 Repaint();
569 }
570
571 public static void OverwriteMessage(String message) {
572 for (int ind = Messages.length - 1; ind >= 0; ind--) {
573 if (Messages[ind] != null) {
574 Messages[ind].setText(getMessagePrefix(false) + message);
575 Repaint();
576 return;
577 }
578 }
579
580 // if we have not returned, then there are no messages yet
581 DisplayMessage(message, Color.darkGray);
582 }
583
584 /**
585 * Displays the given message in the message area of the Frame, any previous
586 * message is cleared from the screen.
587 *
588 * @param message
589 * The message to display to the user in the message area
590 */
591 public static void DisplayMessage(String message) {
592 DisplayMessageAlways(message);
593 }
594
595 public static void DisplayMessage(String message, Color textColor) {
596 displayMessage(message, null, textColor);
597 Misc.Beep();
598 }
599
600 public static void DisplayMessage(Text message) {
601 displayMessage(message.getFirstLine(), message.getLink(), message
602 .getColor());
603 // Misc.Beep();
604 }
605
606 public static void DisplayMessageAlways(String message) {
607 // _lastMessage = null;
608 displayMessage(message, null, Color.BLACK);
609 Misc.Beep();
610 }
611
612 public static void WarningMessage(String message) {
613 displayMessage(message, null, Color.MAGENTA);
614 Misc.Beep();
615 }
616
617 // private static String _lastMessage = null;
618
619 private static void displayMessage(String message, String link, Color color) {
620 // add timestamp to message
621 // if (message.equals(_lastMessage))
622 // return;
623 // _lastMessage = message;
624
625 // message += _formatter.format(Calendar.getInstance().getTime());
626
627 // if the creator needs to be initialised (happens on first message)
628 if (_creator == null) {
629 _creator = new FrameCreator("Messages", true);
630
631 // set up 'Messages' link on the right hand side
632 MessageLink.setPosition(_MaxSize.width - MESSAGE_LINK_Y_OFFSET,
633 MESSAGE_LINK_X);
634 MessageLink.setOffset(0, -_MaxSize.height);
635 }
636
637 // if the message slots have not all been used yet
638 if (_MessageCount <= Messages.length) {
639 int pos = 15;
640 // find the next empty slot, and create the new message
641 for (int i = 0; i < Messages.length; i++) {
642 if (Messages[i] == null) {
643 Messages[i] = new Text(-1, getMessagePrefix(true)
644 + message);
645 Messages[i].setPosition(20, pos);
646 Messages[i].setOffset(0, -_MaxSize.height);
647 Messages[i].setMaxSize(_MaxSize);
648 Messages[i].setColor(color);
649 Messages[i].setLink(link);
650
651 _creator.addItem(Messages[i].copy());
652 MessageLink.setLink(_creator.getCurrent());
653 Repaint();
654 return;
655 }
656
657 pos += 25;
658 }
659 }
660
661 // if we have not returned then all message slots are used
662 for (int i = 0; i < Messages.length - 1; i++) {
663 Messages[i].setText(Messages[i + 1].getFirstLine());
664 Messages[i].setColor(Messages[i + 1].getColor());
665 Messages[i].setLink(Messages[i + 1].getLink());
666 }
667
668 // show the new message
669 Text last = Messages[Messages.length - 1];
670 last.setColor(color);
671 last.setText(getMessagePrefix(true) + message);
672 last.setLink(link);
673
674 _creator.addItem(last.copy());
675 // update the link to the latest message frame
676 MessageLink.setLink(_creator.getCurrent());
677 Repaint();
678 }
679
680 private static String getMessagePrefix(boolean incrementCounter) {
681 if (incrementCounter)
682 _MessageCount++;
683 return "@" + _MessageCount + ": ";
684 }
685
686 /**
687 * Checks if the error message ends with a frame name after the
688 * frameNameSeparator symbol
689 *
690 * @param message
691 * the message to be displayed
692 */
693 public static void LinkedErrorMessage(String message) {
694 if (_SupressErrors)
695 return;
696 Misc.Beep();
697 String[] tokens = message.split(Text.FRAME_NAME_SEPARATOR);
698 String link = null;
699 if (tokens.length > 1)
700 link = tokens[tokens.length - 1];
701 displayMessage(message, link, Color.RED);
702 }
703
704 public static void ErrorMessage(String message) {
705 if (_SupressErrors)
706 return;
707 Misc.Beep();
708 displayMessage(message, null, Color.RED);
709
710 // Michael is confused about why this code is gettting into infinite
711 // loop
712
713 /*
714 * Exception e = new Exception();
715 *
716 * try{ throw e; }catch(Exception ex){ StackTraceElement[] trace =
717 * ex.getStackTrace(); message += " (" + trace[1].getFileName() + ":" +
718 * trace[1].getLineNumber() + ")";
719 *
720 * String source = trace[1].getClassName(); source = "src.java." +
721 * source; source = source.replace(".", File.separator); source +=
722 * ".java";
723 *
724 * try{ BufferedReader reader = new BufferedReader(new
725 * FileReader(source)); FrameCreator creator = new
726 * FrameCreator("Messages", false);
727 *
728 * int min = trace[1].getLineNumber() - 10; int max =
729 * trace[1].getLineNumber() + 3;
730 *
731 * int line = 0; while(reader.ready()){ if(line > min && line < max)
732 * if(line == trace[1].getLineNumber() - 1)
733 * creator.addText(reader.readLine(), Color.RED); else
734 * creator.addText(reader.readLine()); else if(line > max) break; else
735 * reader.readLine();
736 *
737 * line++; }
738 *
739 * reader.close();
740 *
741 * displayMessage(message, creator.getCurrent(), Color.RED);
742 * }catch(Exception ioe){ ioe.printStackTrace(); } }
743 */
744 }
745
746 private class Repainter extends Thread {
747 public boolean isPainting = false;
748
749 public void run() {
750 isPainting = true;
751
752 Frame[] toPaint = DisplayIO.getFrames();
753
754 if (toPaint != null) {
755 VolatileImage left = Paint(toPaint[0]);
756 VolatileImage right = Paint(toPaint[1]);
757 Paint(left, right, DisplayIO.DEFAULT_BACKGROUND);
758 }
759
760 isPainting = false;
761 }
762 }
763
764 /**
765 * Invalidates the buffered image of the current Frame and forces it to be
766 * repainted on to the screen.
767 */
768 public static void ForceRepaint() {
769 Frame current = DisplayIO.getCurrentFrame();
770
771 if (current == null)
772 return;
773
774 Repaint();
775 }
776
777 /**
778 * Repaints the buffer of the given Frame.
779 *
780 * @param toUpdate
781 * The Frame whose buffer is to be repainted.
782 */
783
784 public static void UpdateBuffer(Frame toUpdate, boolean paintOverlays) {
785 if (toUpdate == null)
786 return;
787
788 VolatileImage vi = Paint(toUpdate, paintOverlays);
789 toUpdate.setBuffer(vi);
790 }
791
792 public static void SupressErrors(boolean val) {
793 _SupressErrors = val;
794 }
795
796 private static void repaintPopups(Container parent, Graphics g) {
797 for (Component c : parent.getComponents()) {
798 if (c instanceof JPopupMenu && ((JPopupMenu) c).isVisible()) {
799
800 Point p = SwingUtilities.convertPoint(c, c.getLocation(),
801 Browser._theBrowser.getContentPane());
802
803 g.translate(p.x, p.y);
804 c.paint(g);
805 g.translate(-p.x, -p.y);
806 } else if (c instanceof Container
807 && c != Browser._theBrowser.getContentPane()) {
808 repaintPopups((Container) c, g);
809 }
810 }
811 }
812}
Note: See TracBrowser for help on using the repository browser.