Changeset 121 for trunk/src/org/expeditee/gui/FrameGraphics.java
- Timestamp:
- 07/03/08 16:48:09 (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/gui/FrameGraphics.java
r115 r121 5 5 import java.awt.Container; 6 6 import java.awt.Dimension; 7 import java.awt. Font;7 import java.awt.EventQueue; 8 8 import java.awt.Graphics; 9 9 import java.awt.Graphics2D; … … 11 11 import java.awt.Image; 12 12 import java.awt.Point; 13 import java.awt.Rectangle; 13 14 import java.awt.RenderingHints; 15 import java.awt.geom.Area; 14 16 import java.awt.image.BufferedImage; 15 import java.awt.image.VolatileImage;16 17 import java.util.Collection; 17 18 import java.util.Collections; … … 21 22 import java.util.List; 22 23 24 import javax.swing.JComponent; 23 25 import javax.swing.JPopupMenu; 24 26 import javax.swing.SwingUtilities; 25 27 26 import org.expeditee.actions.Misc;27 28 import org.expeditee.items.Circle; 28 29 import org.expeditee.items.InteractiveWidget; … … 30 31 import org.expeditee.items.ItemUtils; 31 32 import org.expeditee.items.Line; 32 import org.expeditee.items.Text;33 33 import org.expeditee.items.WidgetEdge; 34 34 import org.expeditee.items.XRayable; 35 35 36 36 public class FrameGraphics { 37 public static final int MESSAGE_BUFFER_HEIGHT = 100;38 39 private static final int MESSAGE_LINK_Y_OFFSET = 100;40 41 private static final int MESSAGE_LINK_X = 50;42 37 43 38 // the graphics used to paint with … … 47 42 private static Dimension _MaxSize; 48 43 49 // messages shown in the message window50 public static Text[] Messages = new Text[4];51 52 // buffer of the message window53 private static VolatileImage _MessageBuffer = null;54 55 // font used for the messages56 private static Font _MessageFont = Font.decode("Serif-Plain-16");57 58 // the number of messages currently shown (used for scrolling up)59 private static int _MessageCount = 0;60 61 44 // modes 62 45 public static final int MODE_NORMAL = 0; … … 65 48 66 49 public static final int MODE_XRAY = 2; 67 68 public static final Color ERROR_COLOR = Color.red;69 50 70 51 // Start in XRay mode so that errors arnt thrown when parsing the profile 71 52 // frame if it has images on it 72 53 private static int _Mode = MODE_XRAY; 73 74 // if true, error messages are not shown to the user 75 private static boolean _SupressMessages = false; 76 77 public static String MESSAGES_FRAMESET_NAME = "Messages"; 78 79 // The link to the message frameset 80 public static Item MessageLink = new Text(-2, "@" + MESSAGES_FRAMESET_NAME, 81 Color.black, Color.white); 82 83 // creator for creating the message frames 84 private static FrameCreator _creator; 54 55 private FrameGraphics() { 56 // util constructor 57 } 85 58 86 59 /** … … 104 77 FrameUtils.Parse(current); 105 78 DisplayIO.UpdateTitle(); 106 setMaxSize(new Dimension(_MaxSize.width, _MessageBuffer.getHeight()79 setMaxSize(new Dimension(_MaxSize.width, MessageBay.getMessageBufferHeight() 107 80 + _MaxSize.height)); 108 Repaint();81 refresh(false); 109 82 } 110 83 … … 120 93 DisplayIO.UpdateTitle(); 121 94 FrameMouseActions.getInstance().refreshHighlights(); 122 Repaint();95 refresh(false); 123 96 } 124 97 … … 151 124 // Hide the message buffer if in audience mode 152 125 int newMaxHeight = max.height 153 - (isAudienceMode() ? 0 : M ESSAGE_BUFFER_HEIGHT);126 - (isAudienceMode() ? 0 : MessageBay.MESSAGE_BUFFER_HEIGHT); 154 127 if (newMaxHeight > 0) { 155 128 _MaxSize.setSize(max.width, newMaxHeight); … … 161 134 } 162 135 163 if (newMaxHeight > 0) { 164 _MessageBuffer = null; 165 166 for (int i = 0; i < Messages.length; i++) { 167 if (Messages[i] != null) { 168 Messages[i].setOffset(0, -_MaxSize.height); 169 Messages[i].setMaxSize(_MaxSize); 170 } 171 } 172 173 MessageLink.setOffset(0, -_MaxSize.height); 174 MessageLink.setMaxSize(_MaxSize); 175 MessageLink.setPosition(_MaxSize.width - MESSAGE_LINK_Y_OFFSET, 176 MESSAGE_LINK_X); 177 } 178 // Repaint(); 136 if (newMaxHeight > 0) 137 MessageBay.updateSize(); 179 138 } 180 139 … … 205 164 * Displays the given Item on the screen 206 165 */ 207 privatestatic void PaintItem(Graphics2D g, Item i) {166 static void PaintItem(Graphics2D g, Item i) { 208 167 if (i == null || g == null) 209 168 return; … … 286 245 } 287 246 288 private static Image Paint(Frame toPaint) { 289 return Paint(toPaint, true); 290 } 291 292 private static Image Paint(Frame toPaint, boolean isActualFrame) { 247 private static Image Paint(Frame toPaint, Area clip) { 248 return Paint(toPaint, clip, true); 249 } 250 251 /** 252 * 253 * @param toPaint 254 * @param clip If null, then no clip applied. 255 * @param isActualFrame 256 * @return 257 */ 258 private static Image Paint(Frame toPaint, Area clip, boolean isActualFrame) { 293 259 if (toPaint == null) 294 260 return null; … … 313 279 314 280 Graphics2D bg = (Graphics2D) buffer.getGraphics(); 281 bg.setClip(clip); 282 283 // TODO: Revise images and clip - VERY IMPORTANT 315 284 316 285 // Nicer looking lines, but may be too jerky while … … 331 300 } 332 301 302 333 303 bg.setColor(backgroundColor); 304 // bg.setColor(Color.pink); // TODO: TEMP FOR DEBUGGING 305 334 306 bg.fillRect(0, 0, _MaxSize.width, _MaxSize.height); 335 307 336 List<Item> paintItems = new LinkedList<Item>();308 List<Item> visibleItems = new LinkedList<Item>(); 337 309 List<InteractiveWidget> paintWidgets; 338 310 … … 340 312 // Add all the items for this frame and any other from other 341 313 // frames 342 paintItems.addAll(toPaint.getAllItems()); 343 314 visibleItems.addAll(toPaint.getAllItems()); 344 315 paintWidgets = new LinkedList<InteractiveWidget>(); 345 316 AddAllOverlayWidgets(paintWidgets, toPaint, 346 317 new LinkedList<Frame>()); 347 318 } else { 348 paintItems.addAll(toPaint.getVisibleItems());349 paintItems.addAll(toPaint.getVectorItems());319 visibleItems.addAll(toPaint.getVisibleItems()); 320 visibleItems.addAll(toPaint.getVectorItems()); 350 321 paintWidgets = toPaint.getInteractiveWidgets(); 351 322 } 352 323 353 324 // FIRST: Paint widgets swing gui (not expeditee gui) . 354 // Note that these are the anc ored widgets325 // Note that these are the anchored widgets 355 326 for (InteractiveWidget iw : paintWidgets) { 356 iw.paint(bg); 357 } 358 359 PaintPictures(bg, paintItems); 360 PaintLines(bg, paintItems); 361 327 if (clip == null || clip.intersects(iw.getComponant().getBounds())) 328 iw.paint(bg); 329 } 330 331 // Filter out items that do not need to be painted 332 List<Item> paintItems; 333 HashSet<Item> fillOnlyItems = null; // only contains items that do not need drawing but fills might 334 335 if (clip == null) { 336 paintItems = visibleItems; 337 } else { 338 fillOnlyItems = new HashSet<Item>(); 339 paintItems = new LinkedList<Item>(); 340 for (Item i : visibleItems) { 341 if (i.isInDrawingArea(clip)) { 342 paintItems.add(i); 343 } else if (i.isEnclosed()) { 344 // just add all fill items despite possibility of fills not being in clip 345 // because it will be faster than having to test twice for fills that do need 346 // repainting. 347 fillOnlyItems.add(i); 348 } 349 } 350 } 351 // Only paint files and lines once ... between anchored AND free items 352 HashSet<Item> paintedFillsAndLines = new HashSet<Item> (); 353 PaintPictures(bg, paintItems, fillOnlyItems, paintedFillsAndLines); 354 PaintLines(bg, visibleItems); 355 356 // Filter out free items that do not need to be painted 357 // This is efficient in cases with animation while free items exist 358 359 List<Item> freeItemsToPaint = new LinkedList<Item>(); 360 if (clip == null) { 361 freeItemsToPaint = FreeItems.getInstance(); 362 } else { 363 freeItemsToPaint = new LinkedList<Item>(); 364 fillOnlyItems.clear(); 365 for (Item i : FreeItems.getInstance()) { 366 if (i.isInDrawingArea(clip)) { 367 freeItemsToPaint.add(i); 368 } else if (i.isEnclosed()) { 369 fillOnlyItems.add(i); 370 } 371 } 372 } 373 362 374 if (isActualFrame /* && toPaint == DisplayIO.getCurrentFrame() */) 363 PaintPictures(bg, Frame.FreeItems);364 // TODO if we can get transparency with FreeItems. .. then text can375 PaintPictures(bg, freeItemsToPaint, fillOnlyItems, paintedFillsAndLines); 376 // TODO if we can get transparency with FreeItems.getInstance()... then text can 365 377 // be done before freeItems 366 378 PaintNonLinesNonPicture(bg, paintItems); … … 374 386 if (DisplayIO.isTwinFramesOn()) { 375 387 List<Item> lines = new LinkedList<Item>(); 376 for (Item i : Frame.FreeItems) {388 for (Item i : freeItemsToPaint) { 377 389 if (i instanceof Line) { 378 390 Line line = (Line) i; … … 411 423 // Dont paint the 412 424 if (isActualFrame) 413 PaintLines(bg, Frame.FreeItems);425 PaintLines(bg, freeItemsToPaint); 414 426 } 415 427 416 428 if (isActualFrame /* && toPaint == DisplayIO.getCurrentFrame() */) 417 PaintNonLinesNonPicture(bg, Frame.FreeItems);429 PaintNonLinesNonPicture(bg, freeItemsToPaint); 418 430 419 431 // BROOK: Ensure popups are repainted … … 465 477 } 466 478 467 private static void Paint(Image left, Image right, Color background) { 468 if (_MessageBuffer == null) { 469 GraphicsEnvironment ge = GraphicsEnvironment 470 .getLocalGraphicsEnvironment(); 471 _MessageBuffer = ge.getDefaultScreenDevice() 472 .getDefaultConfiguration().createCompatibleVolatileImage( 473 _MaxSize.width, 474 (isAudienceMode() ? 0 : MESSAGE_BUFFER_HEIGHT)); 475 } 476 477 paintMessage(_MessageBuffer.createGraphics(), background); 478 Graphics g = _DisplayGraphics.create(); 479 private static void Paint(Graphics g, Image left, Image right, Color background) { 479 480 480 481 // if TwinFrames mode is on, then clipping etc has to be set … … 503 504 g.drawImage(right, 0, 0, Item.DEFAULT_BACKGROUND, null); 504 505 } 505 // Dont display the message area in audience mode 506 if (!isAudienceMode()) { 507 // draw the message area 508 g.drawImage(_MessageBuffer, 0, _MaxSize.height, null); 509 } 510 g.dispose(); 511 512 } 513 514 /** 515 * Paints the message area 516 * 517 * @param g 518 * @param background 519 */ 520 private static void paintMessage(Graphics2D g, Color background) { 521 ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, 522 RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 523 g.setColor(background); 524 g.fillRect(0, 0, _MaxSize.width, MESSAGE_BUFFER_HEIGHT); 525 g.setFont(_MessageFont); 526 g.setColor(Color.BLACK); 527 g.drawLine(0, 0, _MaxSize.width, 0); 528 for (Item t : Messages) 529 PaintItem(g, t); 530 if (MessageLink.getLink() != null) 531 PaintItem(g, MessageLink); 532 g.dispose(); 506 533 507 } 534 508 … … 539 513 g.dispose(); 540 514 } 541 542 /**543 * Called to refresh the display screen.544 *545 */546 public static void Repaint() {547 Runtime.getRuntime();548 if (_DisplayGraphics == null)549 return;550 551 if (UserSettings.Threading) {552 if (painter == null) {553 painter = new FrameGraphics().new Repainter();554 555 painter.setDaemon(true);556 painter.setPriority(Thread.MIN_PRIORITY);557 558 painter.start();559 } else560 painter.run();561 } else {562 Frame[] toPaint = DisplayIO.getFrames();563 564 if (toPaint != null) {565 Image left = Paint(toPaint[0]);566 Image right = Paint(toPaint[1]);567 Paint(left, right, Item.DEFAULT_BACKGROUND);568 }569 }570 }571 572 private static Repainter painter = null;573 515 574 516 private static void PaintNonLinesNonPicture(Graphics2D g, List<Item> toPaint) { … … 601 543 } 602 544 545 603 546 /** 604 547 * Paint filled areas and their surrounding lines as well as pictures. 605 * 548 * Note: floating widgets are painted as fills 606 549 * @param g 607 550 * @param toPaint 608 551 */ 609 private static void PaintPictures(Graphics2D g, List<Item> toPaint) { 610 // Use this set to keep track of the items that dont need to be 611 // repainted 612 Collection<Item> done = new HashSet<Item>(); 552 private static void PaintPictures(Graphics2D g, List<Item> toPaint, 553 HashSet<Item> fillOnlyItems, HashSet<Item> done) { 554 613 555 List<Item> toFill = new LinkedList<Item>(); 614 556 for (Item i : toPaint) { … … 634 576 } 635 577 } 578 579 if (fillOnlyItems != null) { 580 for (Item i : fillOnlyItems) { 581 if (done.contains(i)) continue; 582 else if (!isAudienceMode() || !i.isConnectedToAnnotation()) { 583 toFill.add(i); 584 } 585 done.addAll(i.getAllConnected()); 586 } 587 } 588 636 589 // Sort the items to fill 637 590 Collections.sort(toFill, new Comparator<Item>() { … … 639 592 Double aArea = a.getEnclosedArea(); 640 593 Double bArea = b.getEnclosedArea(); 641 return aArea.compareTo(bArea) * -1; 594 int cmp = aArea.compareTo(bArea); 595 if (cmp == 0) { 596 return new Integer(a.getID()).compareTo(b.getID()); 597 } 598 return cmp * -1; 642 599 } 643 600 }); … … 715 672 // Mike: TODO comment on why the line below is used!! 716 673 // I forgot already!!Opps 717 boolean freeItem = Fr ame.FreeItems.contains(item);674 boolean freeItem = FreeItems.getInstance().contains(item); 718 675 for (Item i : item.getAllConnected()) { 719 if (/* freeItem || */!Fr ame.FreeItems.contains(i)) {676 if (/* freeItem || */!FreeItems.getInstance().contains(i)) { 720 677 i.setHighlightMode(connectedNewMode); 721 678 } … … 723 680 if (!freeItem && newMode != connectedNewMode) 724 681 item.setHighlightMode(newMode); 725 Repaint();726 }727 728 public static void OverwriteMessage(String message) {729 for (int ind = Messages.length - 1; ind >= 0; ind--) {730 if (Messages[ind] != null) {731 Messages[ind].setText(getMessagePrefix(false) + message);732 Repaint();733 return;734 }735 }736 737 // if we have not returned, then there are no messages yet738 DisplayMessage(message, Color.darkGray);739 }740 741 /**742 * Displays the given message in the message area of the Frame, any previous743 * message is cleared from the screen.744 *745 * @param message746 * The message to display to the user in the message area747 */748 public static void DisplayMessage(String message) {749 DisplayMessageAlways(message);750 }751 752 public static void DisplayMessageOnce(String message) {753 displayMessage(message, null, null, Color.BLACK, false);754 }755 756 public static void DisplayMessage(String message, Color textColor) {757 displayMessage(message, null, null, textColor);758 // Misc.Beep();759 }760 761 public static void DisplayMessage(Text message) {762 displayMessage(message.getFirstLine(), message.getLink(), message763 .getAction(), message.getColor());764 // Misc.Beep();765 }766 767 public static void DisplayMessageAlways(String message) {768 displayMessage(message, null, null, Color.BLACK);769 // Misc.Beep();770 }771 772 public static void WarningMessage(String message) {773 displayMessage(message, null, null, Color.MAGENTA);774 // Misc.Beep();775 }776 777 private static String _lastMessage = null;778 779 private static void displayMessage(String message, String link,780 List<String> actions, Color color) {781 displayMessage(message, link, actions, color, true);782 }783 784 private static void displayMessage(String message, String link,785 List<String> actions, Color color, boolean displayAlways) {786 787 System.out.println(message);788 assert (message != null);789 790 if (_SupressMessages)791 return;792 793 if (!displayAlways && message.equals(_lastMessage)) {794 Misc.Beep();795 return;796 }797 _lastMessage = message;798 799 if (_creator == null) {800 _creator = new FrameCreator(MESSAGES_FRAMESET_NAME, true);801 802 // set up 'Messages' link on the right hand side803 MessageLink.setPosition(_MaxSize.width - MESSAGE_LINK_Y_OFFSET,804 MESSAGE_LINK_X);805 MessageLink.setOffset(0, -_MaxSize.height);806 }807 808 // if the message slots have not all been used yet809 if (_MessageCount <= Messages.length) {810 int pos = 15;811 // find the next empty slot, and create the new message812 for (int i = 0; i < Messages.length; i++) {813 if (Messages[i] == null) {814 Messages[i] = new Text(getMessagePrefix(true) + message);815 Messages[i].setPosition(20, pos);816 Messages[i].setOffset(0, -_MaxSize.height);817 Messages[i].setMaxSize(_MaxSize);818 Messages[i].setColor(color);819 Messages[i].setLink(link);820 _creator.addItem(Messages[i].copy());821 MessageLink.setLink(_creator.getCurrent());822 Repaint();823 return;824 }825 826 pos += 25;827 }828 }829 830 // if we have not returned then all message slots are used831 for (int i = 0; i < Messages.length - 1; i++) {832 Messages[i].setText(Messages[i + 1].getFirstLine());833 Messages[i].setColor(Messages[i + 1].getColor());834 Messages[i].setLink(Messages[i + 1].getLink());835 }836 837 // show the new message838 Text last = Messages[Messages.length - 1];839 last.setColor(color);840 // Make set the text for the new message841 last.setText(getMessagePrefix(true) + message);842 last.setLink(link);843 last.setActions(actions);844 845 _creator.addItem(last.copy());846 // update the link to the latest message frame847 MessageLink.setLink(_creator.getCurrent());848 Repaint();849 }850 851 private static String getMessagePrefix(boolean incrementCounter) {852 if (incrementCounter)853 _MessageCount++;854 return "@" + _MessageCount + ": ";855 }856 857 /**858 * Checks if the error message ends with a frame name after the859 * frameNameSeparator symbol860 *861 * @param message862 * the message to be displayed863 */864 public static void LinkedErrorMessage(String message) {865 if (_SupressMessages)866 return;867 Misc.Beep();868 String[] tokens = message.split(Text.FRAME_NAME_SEPARATOR);869 String link = null;870 if (tokens.length > 1)871 link = tokens[tokens.length - 1];872 displayMessage(message, link, null, ERROR_COLOR);873 }874 875 public static void ErrorMessage(String message) {876 if (_SupressMessages)877 return;878 Misc.Beep();879 displayMessage(message, null, null, ERROR_COLOR);880 }881 882 private class Repainter extends Thread {883 public boolean isPainting = false;884 885 public void run() {886 // TODO see if there is any other way to deal with this887 if (_MaxSize.width <= 0 || _MaxSize.height <= 0) {888 return;889 }890 isPainting = true;891 892 Frame[] toPaint = DisplayIO.getFrames();893 894 if (toPaint != null) {895 Image left = Paint(toPaint[0]);896 Image right = Paint(toPaint[1]);897 Paint(left, right, Item.DEFAULT_BACKGROUND);898 }899 isPainting = false;900 }901 }902 903 /**904 * Invalidates the buffered image of the current Frame and forces it to be905 * repainted on to the screen.906 */907 public static void ForceRepaint() {908 Frame current = DisplayIO.getCurrentFrame();909 910 if (current == null)911 return;912 913 682 Repaint(); 914 683 } … … 925 694 return; 926 695 927 Image vi = Paint(toUpdate, paintOverlays);696 Image vi = Paint(toUpdate, null, paintOverlays); 928 697 toUpdate.setBuffer(vi); 929 }930 931 public static void SupressMessages(boolean val) {932 _SupressMessages = val;933 698 } 934 699 … … 939 704 Browser._theBrowser.getContentPane()); 940 705 706 c.setIgnoreRepaint(true); 707 ((JComponent)c).setDoubleBuffered(false); 941 708 g.translate(p.x, p.y); 942 709 c.paint(g); … … 952 719 return _Mode; 953 720 } 721 722 // Damaged areas pending to render. Accessessed by multiple threads 723 private static HashSet<Rectangle> damagedAreas = new HashSet<Rectangle>(); 724 725 /** 726 * Checks that the item is visible (on current frame && overlays) - if visible 727 * then damaged area will be re-rendered on the next refresh. 728 * @param damagedItem 729 * @param toRepaint 730 */ 731 public static void invalidateItem(Item damagedItem, Rectangle toRepaint) { 732 // Only add area to repaint if item is visible... 733 if (ItemUtils.isVisible(damagedItem)) { 734 synchronized(damagedAreas) { 735 damagedAreas.add(toRepaint); 736 } 737 } else if(MessageBay.isMessageItem(damagedItem)) { 738 MessageBay.addDirtyArea(toRepaint); 739 } 740 } 741 742 /** 743 * The given area will be re-rendered in the next refresh. This is the quicker version 744 * and is more useful for re-rendering animated areas. 745 * @param toRepaint 746 */ 747 public static void invalidateArea(Rectangle toRepaint) { 748 synchronized(damagedAreas) { 749 damagedAreas.add(toRepaint); 750 } 751 } 752 753 public static void clearInvalidAreas() { 754 synchronized(damagedAreas) { 755 damagedAreas.clear(); 756 } 757 } 758 759 /** 760 * Invalidates the buffered image of the current Frame and forces it to be 761 * repainted on to the screen. Repaints all items. This is more expensive 762 * than refresh. 763 */ 764 public static void ForceRepaint() { // TODO: TEMP: Use refresh 765 Frame current = DisplayIO.getCurrentFrame(); 766 767 if (current == null) 768 return; 769 refresh(false); 770 } 771 772 public static void Repaint() { // TODO: TEMP: Use refresh 773 refresh(true); 774 } 775 776 /** 777 * Called to refresh the display screen. Thread safe. 778 */ 779 public static void refresh(boolean useInvalidation) { 780 781 if (_DisplayGraphics == null) return; 782 783 Area clip = null; 784 if (useInvalidation) { // build clip 785 786 synchronized(damagedAreas) { 787 if (!damagedAreas.isEmpty()) { 788 789 for (Rectangle r : damagedAreas) { 790 if (clip == null) clip = new Area(r); 791 clip.add(new Area(r)); 792 } 793 damagedAreas.clear(); 794 } else return; // nothing to render 795 } 796 797 } else { 798 synchronized(damagedAreas) { 799 damagedAreas.clear(); 800 } 801 System.out.println("FULLSCREEN REFRESH"); // TODO: REMOVE 802 } 803 804 Frame[] toPaint = DisplayIO.getFrames(); 805 Image left = Paint(toPaint[0], clip); 806 Image right = Paint(toPaint[1], clip); 807 808 Graphics dg = _DisplayGraphics.create(); 809 810 // Paint frame to window 811 Paint(dg, left, right, Item.DEFAULT_BACKGROUND); 812 813 // Paint message bay 814 MessageBay.refresh(useInvalidation, dg, Item.DEFAULT_BACKGROUND); 815 816 dg.dispose(); 817 } 818 819 /** 820 * If wanting to refresh from another thread - other than the main thread that 821 * handles the expeditee datamodel (modifying / accessing / rendering). Use 822 * this method for thread safety. 823 */ 824 public static synchronized void requestRefresh(boolean useInvalidation) { 825 826 _requestMarsheller._useInvalidation = useInvalidation; 827 828 if (_requestMarsheller._isQueued) { 829 return; 830 } 831 832 _requestMarsheller._isQueued = true; 833 EventQueue.invokeLater(_requestMarsheller); // Render on AWT thread 834 } 835 836 private static RenderRequestMarsheller _requestMarsheller = new FrameGraphics().new RenderRequestMarsheller(); 837 838 /** 839 * Used for marshelling render requests from foreign threads to the event dispatcher thread... (AWT) 840 * @author Brook Novak 841 */ 842 private class RenderRequestMarsheller implements Runnable { 843 844 boolean _useInvalidation = true; 845 boolean _isQueued = false; 846 847 public void run() { 848 refresh(_useInvalidation); 849 _isQueued = false; 850 _useInvalidation = true; 851 } 852 853 } 854 954 855 }
Note:
See TracChangeset
for help on using the changeset viewer.