예제 #1
0
  /**
   * Moves this piece to a new position on the board.
   *
   * @param newRow The destination row.
   * @param newColumn The destination column.
   * @return <code>false</code> if the destination is not a legal board position, or if the piece is
   *     already moving.
   */
  public boolean moveTo(int newRow, int newColumn) {
    if (!board.isLegalPosition(newRow, newColumn)) return false;
    if (moving) return false;
    int startX = board.columnToX(column);
    int startY = board.rowToY(row);
    int finishX = board.columnToX(newColumn);
    int finishY = board.rowToY(newRow);
    int changeInX = finishX - startX;
    int changeInY = finishY - startY;
    Rectangle oldRect = getRectangle();
    Rectangle newRect = new Rectangle(oldRect);

    // compensate for squares being slightly different sizes
    oldRect.width += 2;
    newRect.width += 2;
    oldRect.height += 2;
    newRect.height += 2;

    // Move smoothly towards new position
    moving = true;
    board.moveToTop(this);
    int deltaRow = Math.abs(row - newRow);
    int deltaColumn = Math.abs(column - newColumn);
    int distance = Math.max(deltaRow, deltaColumn) + Math.min(deltaRow, deltaColumn) / 2;
    int numberOfSteps = distance * FRAME_RATE / getSpeed();

    for (int i = 1; i <= numberOfSteps; i++) {
      oldRect.x = x;
      oldRect.y = y;
      x = startX + (i * changeInX) / numberOfSteps;
      y = startY + (i * changeInY) / numberOfSteps;
      newRect.x = x;
      newRect.y = y;
      board.getJPanel().paintImmediately(oldRect.union(newRect));
      //            redraw(oldRect.union(newRect));

      try {
        Thread.sleep(PAUSE_MS);
      } catch (InterruptedException e) {
        /* Deliberately empty */
      }
    }
    moving = false;
    if (canMoveTo(newRow, newColumn)) {
      changePosition(newRow, newColumn);
    }
    redraw(oldRect.union(newRect));
    return true;
  }
예제 #2
0
 @Override
 public void mouseMoved(MouseEvent e) {
   Point pt = e.getPoint();
   int prevRow = row;
   int prevCol = col;
   row = table.rowAtPoint(pt);
   col = table.columnAtPoint(pt);
   if (row < 0 || col < 0) {
     row = -1;
     col = -1;
   }
   // >>>> HyperlinkCellRenderer.java
   // @see
   // http://java.net/projects/swingset3/sources/svn/content/trunk/SwingSet3/src/com/sun/swingset3/demos/table/HyperlinkCellRenderer.java
   if (row == prevRow && col == prevCol) {
     return;
   }
   Rectangle repaintRect;
   if (row >= 0 && col >= 0) {
     Rectangle r = table.getCellRect(row, col, false);
     if (prevRow >= 0 && prevCol >= 0) {
       repaintRect = r.union(table.getCellRect(prevRow, prevCol, false));
     } else {
       repaintRect = r;
     }
   } else {
     repaintRect = table.getCellRect(prevRow, prevCol, false);
   }
   table.repaint(repaintRect);
   // <<<<
   // table.repaint();
 }
    /**
     * Paints a highlight.
     *
     * @param g the graphics context
     * @param offs0 the starting model offset &gt;= 0
     * @param offs1 the ending model offset &gt;= offs1
     * @param bounds the bounding box for the highlight
     * @param c the editor
     */
    public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
      Rectangle alloc = bounds.getBounds();
      try {
        // --- determine locations ---
        TextUI mapper = c.getUI();
        Rectangle p0 = mapper.modelToView(c, offs0);
        Rectangle p1 = mapper.modelToView(c, offs1);

        // --- render ---
        Color color = getColor();

        if (color == null) {
          g.setColor(c.getSelectionColor());
        } else {
          g.setColor(color);
        }
        if (p0.y == p1.y) {
          // same line, render a rectangle
          Rectangle r = p0.union(p1);
          g.fillRect(r.x, r.y, r.width, r.height);
        } else {
          // different lines
          int p0ToMarginWidth = alloc.x + alloc.width - p0.x;
          g.fillRect(p0.x, p0.y, p0ToMarginWidth, p0.height);
          if ((p0.y + p0.height) != p1.y) {
            g.fillRect(alloc.x, p0.y + p0.height, alloc.width, p1.y - (p0.y + p0.height));
          }
          g.fillRect(alloc.x, p1.y, (p1.x - alloc.x), p1.height);
        }
      } catch (BadLocationException e) {
        // can't render
      }
    }
예제 #4
0
  /**
   * Applies this geometry to a window. Makes sure that the window is not placed outside of the
   * coordinate range of all available screens.
   *
   * @param window the window
   */
  public void applySafe(Window window) {
    Point p = new Point(topLeft);

    Rectangle virtualBounds = new Rectangle();
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    for (GraphicsDevice gd : gs) {
      if (gd.getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
        virtualBounds = virtualBounds.union(gd.getDefaultConfiguration().getBounds());
      }
    }

    if (p.x < virtualBounds.x) {
      p.x = virtualBounds.x;
    } else if (p.x > virtualBounds.x + virtualBounds.width - extent.width) {
      p.x = virtualBounds.x + virtualBounds.width - extent.width;
    }

    if (p.y < virtualBounds.y) {
      p.y = virtualBounds.y;
    } else if (p.y > virtualBounds.y + virtualBounds.height - extent.height) {
      p.y = virtualBounds.y + virtualBounds.height - extent.height;
    }

    window.setLocation(p);
    window.setSize(extent);
  }
예제 #5
0
  @Override
  public void actionPerformed(ActionEvent e) {
    // Send tiles to be rendered
    if ((!tilesWaitingToBeRendered.isEmpty())
        && ((System.currentTimeMillis() - lastTileChange) > 250)) {
      tilesWaitingToBeRendered.forEach(threeDeeRenderManager::renderTile);
      tilesWaitingToBeRendered.clear();
    }

    // Collect rendered tiles
    Set<RenderResult> renderResults = threeDeeRenderManager.getRenderedTiles();
    Rectangle repaintArea = null;
    for (RenderResult renderResult : renderResults) {
      Tile tile = renderResult.getTile();
      int x = tile.getX(), y = tile.getY();
      renderedTiles.put(tile, renderResult.getImage());
      Rectangle tileBounds = zoom(getTileBounds(x, y));
      if (repaintArea == null) {
        repaintArea = tileBounds;
      } else {
        repaintArea = repaintArea.union(tileBounds);
      }
    }
    if (repaintArea != null) {
      //            System.out.println("Repainting " + repaintArea);
      repaint(repaintArea);
    }
  }
  /**
   * Determines the containment rectangles.
   *
   * @see #getContainmentRectangles()
   * @see #getOverlappingContainmentRectangles()
   */
  protected void initializeContainmentRectangles() {
    containmentRectangles = new ArrayList<Rectangle>();
    overlappingContainmentRectangles = new ArrayList<Rectangle>();

    // first add all pads
    if (getTopPad() != null) containmentRectangles.add(getTopPad());
    if (getRightPad() != null) containmentRectangles.add(getRightPad());
    if (getBottomPad() != null) containmentRectangles.add(getBottomPad());

    // then add all buttons which are not completely inside already added
    // rectangles (mostly they will be inside the pads)
    for (PositionedContextButton button : getPositionedContextButtons()) {
      boolean buttonInside = false;
      for (Rectangle rectangle : containmentRectangles) {
        if (rectangle.contains(button.getPosition())) {
          buttonInside = true;
          break;
        }
      }
      if (!buttonInside) {
        containmentRectangles.add(button.getPosition());
      }
    }

    // create the overlapping containment rectangles from the just chosen
    // containment rectangles
    Rectangle r = getOriginalReferenceRectangle();
    Point referencePoint = new Point(r.x + (r.width / 2), r.y + (r.height / 2));
    for (Rectangle rectangle : containmentRectangles) {
      Rectangle unionRectangle = rectangle.union(new Rectangle(referencePoint));
      overlappingContainmentRectangles.add(unionRectangle);
    }
    // and add the original reference rectangle itself
    overlappingContainmentRectangles.add(getOriginalReferenceRectangle());
  }
예제 #7
0
  /**
   * Selects a range of text in a text component. If the new selection is outside of the previous
   * viewable rectangle, then the view is centered around the new selection.
   *
   * @param textArea The text component whose selection is to be centered.
   * @param start The start of the range to select.
   * @param end The end of the range to select.
   */
  private static void selectAndPossiblyCenter(JTextArea textArea, int start, int end) {

    textArea.setSelectionStart(start);
    textArea.setSelectionEnd(end);

    Rectangle r = null;
    try {
      r = textArea.modelToView(start);
      if (r == null) { // Not yet visible; i.e. JUnit tests
        return;
      }
      if (end != start) {
        r = r.union(textArea.modelToView(end));
      }
    } catch (BadLocationException ble) { // Never happens
      ble.printStackTrace();
      textArea.setSelectionStart(start);
      textArea.setSelectionEnd(end);
      return;
    }

    Rectangle visible = textArea.getVisibleRect();

    // If the new selection is already in the view, don't scroll,
    // as that is visually jarring.
    if (visible.contains(r)) {
      textArea.setSelectionStart(start);
      textArea.setSelectionEnd(end);
      return;
    }

    visible.x = r.x - (visible.width - r.width) / 2;
    visible.y = r.y - (visible.height - r.height) / 2;

    Rectangle bounds = textArea.getBounds();
    Insets i = textArea.getInsets();
    bounds.x = i.left;
    bounds.y = i.top;
    bounds.width -= i.left + i.right;
    bounds.height -= i.top + i.bottom;

    if (visible.x < bounds.x) {
      visible.x = bounds.x;
    }

    if (visible.x + visible.width > bounds.x + bounds.width) {
      visible.x = bounds.x + bounds.width - visible.width;
    }

    if (visible.y < bounds.y) {
      visible.y = bounds.y;
    }

    if (visible.y + visible.height > bounds.y + bounds.height) {
      visible.y = bounds.y + bounds.height - visible.height;
    }

    textArea.scrollRectToVisible(visible);
  }
예제 #8
0
 /**
  * Method getRowBounds
  *
  * @param table JTable
  * @param first int
  * @param last int
  * @return Rectangle
  */
 private Rectangle getRowBounds(JTable table, int first, int last) {
   Rectangle result = table.getCellRect(first, -1, true);
   result = result.union(table.getCellRect(last, -1, true));
   final Insets insets = table.getInsets();
   result.x = insets.left;
   result.width = table.getWidth() - insets.left - insets.right;
   return result;
 }
예제 #9
0
 private Rectangle union(Rectangle a, Rectangle b) {
   if (a == null) {
     return b;
   }
   if (b == null) {
     return a;
   }
   return a.union(b);
 }
예제 #10
0
 @Override
 public Rectangle getBounds() {
   if (_bounds == null) {
     _bounds = new Rectangle();
     for (int i = 0; i < Screen.getNumberScreens(); i++) {
       _bounds = _bounds.union(Screen.getBounds(i));
     }
   }
   return _bounds;
 }
예제 #11
0
 /**
  * Constructs a ShapeIcon.
  *
  * @param shape the shape to draw
  * @param decoration a decorating shape to draw
  * @param width width of the icon
  * @param height height of the icon
  */
 public ShapeIcon(Shape shape, Shape decoration, int width, int height) {
   w = width;
   h = height;
   this.shape = shape;
   this.decoration = decoration;
   Rectangle rect = shape == null ? new Rectangle() : shape.getBounds();
   if (decoration != null) rect = rect.union(decoration.getBounds());
   offsetX = w / 2 - rect.width / 2 - rect.x;
   offsetY = h / 2 - rect.height / 2 - rect.y;
 }
예제 #12
0
 /**
  * Repaint the given line range.
  *
  * @param line0 The starting line number to repaint. This must be a valid line number in the
  *     model.
  * @param line1 The ending line number to repaint. This must be a valid line number in the model.
  * @param a The region allocated for the view to render into.
  * @param host The component hosting the view (used to call repaint).
  */
 protected void damageLineRange(int line0, int line1, Shape a, Component host) {
   if (a != null) {
     Rectangle area0 = lineToRect(a, line0);
     Rectangle area1 = lineToRect(a, line1);
     if ((area0 != null) && (area1 != null)) {
       Rectangle dmg = area0.union(area1); // damage.
       host.repaint(dmg.x, dmg.y, dmg.width, dmg.height);
     } else host.repaint();
   }
 }
예제 #13
0
  @Override
  public void setGraph(Graph<? extends Vertex, ? extends Edge> g) {
    this.graph = g;
    Rectangle r = new Rectangle();

    for (Vertex v : g.vertexSet()) {
      r = r.union(v.getBounds());
    }
    canvasSize =
        new Dimension((int) Math.ceil(r.getWidth()) + 20, (int) Math.ceil(r.getHeight()) + 20);
  }
예제 #14
0
 /** Returns a rectangle enclosing all the rectangles in the argument. */
 private static Rectangle getSum(Rectangle[] array) {
   Rectangle sum = null;
   for (int a = 0; a < array.length; a++) {
     if (array[a].width > 0 && array[a].height > 0) {
       if (sum == null) {
         sum = new Rectangle(array[a]);
       } else {
         sum = sum.union(array[a]);
       }
     }
   }
   if (sum == null) sum = new Rectangle(0, 0, 0, 0);
   return sum;
 }
 /**
  * Gets the maximum drawing area containing graphics
  *
  * @return
  */
 public Dimension getDrawingArea() {
   Rectangle2D area = new Rectangle(0, 0);
   for (VisreedNode node : this.getHigraph().getTops()) {
     NodeView<
             VisreedPayload,
             VisreedEdgeLabel,
             VisreedHigraph,
             VisreedWholeGraph,
             VisreedSubgraph,
             VisreedNode,
             VisreedEdge>
         nodeView = this.getNodeView(node);
     Rectangle.union(area, nodeView.getNextExtent(), area);
   }
   return new Dimension((int) area.getWidth() + 1, (int) area.getHeight() + 1);
 }
예제 #16
0
    /**
     * Terminates the drag process, putting the dragged piece in the nearest square.
     *
     * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
     */
    @Override
    public void mouseReleased(MouseEvent e) {
      if (pieceBeingDragged == null) return;
      Rectangle oldRect = pieceBeingDragged.getRectangle();
      Rectangle newRect = oldRect;
      int newRow = board.yToRow(pieceBeingDragged.y + board.getCellHeight() / 2);
      int newColumn = board.xToColumn(pieceBeingDragged.x + board.getCellWidth() / 2);

      if (pieceBeingDragged.canMoveTo(newRow, newColumn)) {
        pieceBeingDragged.changePosition(newRow, newColumn);
      }
      pieceBeingDragged.moving = false;
      newRect = pieceBeingDragged.getRectangle();
      pieceBeingDragged.redraw(pieceBeingDragged.enlarge(oldRect.union(newRect)));
      board.dragEvent.reportEvent(pieceBeingDragged);
      pieceBeingDragged = null;
    }
예제 #17
0
  /**
   * Paints the grid lines within <I>aRect</I>, using the grid color set with <I>setGridColor</I>.
   * Paints vertical lines if <code>
   * getShowVerticalLines()</code> returns true and paints horizontal lines if <code>
   * getShowHorizontalLines()</code> returns true. TODO See if we want to remove this method.
   *
   * @param context the Synth context.
   * @param g the Graphics context.
   * @param rMin DOCUMENT ME!
   * @param rMax DOCUMENT ME!
   * @param cMin DOCUMENT ME!
   * @param cMax DOCUMENT ME!
   */
  @SuppressWarnings("unused")
  private void paintGrid(
      SeaGlassContext context, Graphics g, int rMin, int rMax, int cMin, int cMax) {
    g.setColor(table.getGridColor());

    Rectangle minCell = table.getCellRect(rMin, cMin, true);
    Rectangle maxCell = table.getCellRect(rMax, cMax, true);
    Rectangle damagedArea = minCell.union(maxCell);
    SynthGraphicsUtils synthG = context.getStyle().getGraphicsUtils(context);

    if (table.getShowHorizontalLines()) {
      int tableWidth = damagedArea.x + damagedArea.width;
      int y = damagedArea.y;

      for (int row = rMin; row <= rMax; row++) {
        y += table.getRowHeight(row);
        synthG.drawLine(context, "Table.grid", g, damagedArea.x, y - 1, tableWidth - 1, y - 1);
      }
    }

    if (table.getShowVerticalLines()) {
      TableColumnModel cm = table.getColumnModel();
      int tableHeight = damagedArea.y + damagedArea.height;
      int x;

      if (table.getComponentOrientation().isLeftToRight()) {
        x = damagedArea.x;
        for (int column = cMin; column <= cMax; column++) {
          int w = cm.getColumn(column).getWidth();

          x += w;
          synthG.drawLine(context, "Table.grid", g, x - 1, 0, x - 1, tableHeight - 1);
        }
      } else {
        x = damagedArea.x;
        for (int column = cMax; column >= cMin; column--) {
          int w = cm.getColumn(column).getWidth();

          x += w;
          synthG.drawLine(context, "Table.grid", g, x - 1, 0, x - 1, tableHeight - 1);
        }
      }
    }
  }
예제 #18
0
 /**
  * Called from various places that find fault with a block during yail production. It puts a
  * message in the block's Complaint balloon.
  *
  * @param complaint
  * @param severe true means fatal error
  */
 public void complain(String complaint, boolean severe) {
   if (severe) {
     compileErrors.add(complaint);
   }
   RenderableBlock rb = RenderableBlock.getRenderableBlock(blockID);
   String message = (severe ? "Error" : "Warning") + ": " + complaint + "\n";
   Complaint balloon = rb.getComplaint();
   if (!balloon.getText().contains(message)) {
     balloon.setText(message + balloon.getText());
   }
   balloon.getBlockNoteLabel().setActive(severe);
   balloon.getBlockNoteLabel().setBackground(severe ? ERROR_COLOR : WARNING_COLOR);
   if (!rb.isVisible()) {
     // The only way this block is not visible is if it belongs to a collapsed
     // clump. Expand the whole clump so user can see the complaint.
     rb.getTopmost().setCollapsed(false);
   }
   complaintRect = complaintRect.union(rb.getBounds().union(balloon.getBounds()));
   balloon.reformBlockNote();
 }
예제 #19
0
  protected void paintFocus(
      Graphics g, AbstractButton b, Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {

    Rectangle focusRect = new Rectangle();
    String text = b.getText();
    boolean isIcon = b.getIcon() != null;

    // If there is text
    if (text != null && !text.equals("")) {
      if (!isIcon) {
        focusRect.setBounds(textRect);
      } else {
        focusRect.setBounds(iconRect.union(textRect));
      }
    }
    // If there is an icon and no text
    else if (isIcon) {
      focusRect.setBounds(iconRect);
    }

    g.setColor(getFocusColor());
    g.drawRect((focusRect.x - 1), (focusRect.y - 1), focusRect.width + 1, focusRect.height + 1);
  }
예제 #20
0
  private String layoutMenuItem(
      FontMetrics fontmetrics,
      String text,
      Icon icon,
      Icon checkIcon,
      Icon arrowIcon,
      int verticalAlignment,
      int horizontalAlignment,
      int verticalTextPosition,
      int horizontalTextPosition,
      Rectangle viewRect,
      Rectangle iconRect,
      Rectangle textRect,
      Rectangle acceleratorRect,
      Rectangle checkIconRect,
      Rectangle arrowIconRect,
      int textIconGap,
      int menuItemGap) {
    SwingUtilities.layoutCompoundLabel(
        menuItem,
        fontmetrics,
        text,
        icon,
        verticalAlignment,
        horizontalAlignment,
        verticalTextPosition,
        horizontalTextPosition,
        viewRect,
        iconRect,
        textRect,
        textIconGap);
    acceleratorRect.width = acceleratorRect.height = 0;

    /* Initialize the checkIcon bounds rectangle's width & height.
     */
    if (useCheckAndArrow()) {
      if (checkIcon != null) {
        checkIconRect.width = checkIcon.getIconWidth();
        checkIconRect.height = checkIcon.getIconHeight();
      } else {
        checkIconRect.width = checkIconRect.height = 0;
      }

      /* Initialize the arrowIcon bounds rectangle width & height.
       */
      if (arrowIcon != null) {
        arrowIconRect.width = arrowIcon.getIconWidth();
        arrowIconRect.height = arrowIcon.getIconHeight();
      } else {
        arrowIconRect.width = arrowIconRect.height = 0;
      }
      textRect.x += myMaxGutterIconWidth;
      iconRect.x += myMaxGutterIconWidth;
    }
    textRect.x += menuItemGap;
    iconRect.x += menuItemGap;
    Rectangle labelRect = iconRect.union(textRect);

    // Position the Accelerator text rect

    acceleratorRect.x += viewRect.width - arrowIconRect.width - menuItemGap - acceleratorRect.width;
    acceleratorRect.y = (viewRect.y + viewRect.height / 2) - acceleratorRect.height / 2;

    // Position the Check and Arrow Icons

    if (useCheckAndArrow()) {
      arrowIconRect.x += viewRect.width - arrowIconRect.width;
      arrowIconRect.y = (viewRect.y + labelRect.height / 2) - arrowIconRect.height / 2;
      if (checkIcon != null) {
        checkIconRect.y = (viewRect.y + labelRect.height / 2) - checkIconRect.height / 2;
        checkIconRect.x += (viewRect.x + myMaxGutterIconWidth / 2) - checkIcon.getIconWidth() / 2;
        a = viewRect.x;
        e = (viewRect.y + labelRect.height / 2) - myMaxGutterIconWidth / 2;
        k = viewRect.x + myMaxGutterIconWidth + 2;
      } else {
        checkIconRect.x = checkIconRect.y = 0;
      }
    }
    return text;
  }
예제 #21
0
  /**
   * DOCUMENT ME!
   *
   * @param context DOCUMENT ME!
   * @param g DOCUMENT ME!
   * @param rMin DOCUMENT ME!
   * @param rMax DOCUMENT ME!
   * @param draggedColumn DOCUMENT ME!
   * @param distance DOCUMENT ME!
   */
  private void paintDraggedArea(
      SeaGlassContext context,
      Graphics g,
      int rMin,
      int rMax,
      TableColumn draggedColumn,
      int distance) {
    int draggedColumnIndex = viewIndexForColumn(draggedColumn);

    Rectangle minCell = table.getCellRect(rMin, draggedColumnIndex, true);
    Rectangle maxCell = table.getCellRect(rMax, draggedColumnIndex, true);

    Rectangle vacatedColumnRect = minCell.union(maxCell);

    // Paint a gray well in place of the moving column.
    g.setColor(table.getParent().getBackground());
    g.fillRect(
        vacatedColumnRect.x,
        vacatedColumnRect.y,
        vacatedColumnRect.width,
        vacatedColumnRect.height);

    // Move to the where the cell has been dragged.
    vacatedColumnRect.x += distance;

    // Fill the background.
    g.setColor(context.getStyle().getColor(context, ColorType.BACKGROUND));
    g.fillRect(
        vacatedColumnRect.x,
        vacatedColumnRect.y,
        vacatedColumnRect.width,
        vacatedColumnRect.height);

    SynthGraphicsUtils synthG = context.getStyle().getGraphicsUtils(context);

    // Paint the vertical grid lines if necessary.
    if (table.getShowVerticalLines()) {
      g.setColor(table.getGridColor());
      int x1 = vacatedColumnRect.x;
      int y1 = vacatedColumnRect.y;
      int x2 = x1 + vacatedColumnRect.width - 1;
      int y2 = y1 + vacatedColumnRect.height - 1;
      // Left
      synthG.drawLine(context, "Table.grid", g, x1 - 1, y1, x1 - 1, y2);
      // Right
      synthG.drawLine(context, "Table.grid", g, x2, y1, x2, y2);
    }

    for (int row = rMin; row <= rMax; row++) {
      // Render the cell value
      Rectangle r = table.getCellRect(row, draggedColumnIndex, false);

      r.x += distance;
      paintCell(context, g, r, row, draggedColumnIndex);

      // Paint the (lower) horizontal grid line if necessary.
      if (table.getShowHorizontalLines()) {
        g.setColor(table.getGridColor());
        Rectangle rcr = table.getCellRect(row, draggedColumnIndex, true);

        rcr.x += distance;
        int x1 = rcr.x;
        int y1 = rcr.y;
        int x2 = x1 + rcr.width - 1;
        int y2 = y1 + rcr.height - 1;

        synthG.drawLine(context, "Table.grid", g, x1, y2, x2, y2);
      }
    }
  }
  /**
   * Selects a range of text in a text component. If the new selection is outside of the previous
   * viewable rectangle, then the view is centered around the new selection.
   *
   * @param textArea The text component whose selection is to be centered.
   * @param start The start of the range to select.
   * @param end The end of the range to select.
   */
  private static void selectAndPossiblyCenter(JTextArea textArea, int start, int end) {

    boolean foldsExpanded = false;
    if (textArea instanceof RSyntaxTextArea) {
      RSyntaxTextArea rsta = (RSyntaxTextArea) textArea;
      FoldManager fm = rsta.getFoldManager();
      if (fm.isCodeFoldingSupportedAndEnabled()) {
        foldsExpanded = fm.ensureOffsetNotInClosedFold(start);
        foldsExpanded |= fm.ensureOffsetNotInClosedFold(end);
      }
    }

    textArea.setSelectionStart(start);
    textArea.setSelectionEnd(end);

    Rectangle r = null;
    try {
      r = textArea.modelToView(start);
      if (r == null) { // Not yet visible; i.e. JUnit tests
        return;
      }
      if (end != start) {
        r = r.union(textArea.modelToView(end));
      }
    } catch (BadLocationException ble) { // Never happens
      ble.printStackTrace();
      textArea.setSelectionStart(start);
      textArea.setSelectionEnd(end);
      return;
    }

    Rectangle visible = textArea.getVisibleRect();

    // If the new selection is already in the view, don't scroll,
    // as that is visually jarring.
    if (!foldsExpanded && visible.contains(r)) {
      textArea.setSelectionStart(start);
      textArea.setSelectionEnd(end);
      return;
    }

    visible.x = r.x - (visible.width - r.width) / 2;
    visible.y = r.y - (visible.height - r.height) / 2;

    Rectangle bounds = textArea.getBounds();
    Insets i = textArea.getInsets();
    bounds.x = i.left;
    bounds.y = i.top;
    bounds.width -= i.left + i.right;
    bounds.height -= i.top + i.bottom;

    if (visible.x < bounds.x) {
      visible.x = bounds.x;
    }

    if (visible.x + visible.width > bounds.x + bounds.width) {
      visible.x = bounds.x + bounds.width - visible.width;
    }

    if (visible.y < bounds.y) {
      visible.y = bounds.y;
    }

    if (visible.y + visible.height > bounds.y + bounds.height) {
      visible.y = bounds.y + bounds.height - visible.height;
    }

    textArea.scrollRectToVisible(visible);
  }
    /**
     * Implements a strategy to render contents depending on the position of these
     *
     * @param g Graphics
     * @param pos0 the beginning
     * @param pos1 the end
     * @param bounds the bounds
     * @param c the text component where to paint
     */
    public void paint(Graphics g, int pos0, int pos1, Shape bounds, JTextComponent c) {
      try {
        Rectangle alloc = bounds.getBounds();
        Rectangle p0 = c.modelToView(pos0);
        Rectangle p1 = c.modelToView(pos1);
        g.setColor(color);

        if (p0.y == p1.y) {
          Rectangle r = p0.union(p1);
          if (filled) {
            g.fillRect(r.x, r.y, r.width, r.height);
          } else {
            g.drawRect(r.x, r.y, r.width - 1, r.height - 1);
          }
        } else {
          Element root = doc.getDefaultRootElement();
          int line0 = root.getElementIndex(pos0);
          int line1 = root.getElementIndex(pos1);
          Rectangle r0 = c.modelToView(root.getElement(line0).getEndOffset());
          Rectangle r1 = c.modelToView(root.getElement(line1).getStartOffset());
          if (line0 != line1) {
            if (!strict) {
              if (filled) {
                g.fillRect(p0.x, p0.y, alloc.width, p0.height);
                g.fillRect(alloc.x, p0.y + p0.height, alloc.width, r0.y - p0.y - p0.height);

                if (r1.y != p1.y) {
                  g.fillRect(r1.x, r1.y, alloc.width, r1.height);
                }
                g.fillRect(r1.x, p1.y, p1.x, r1.height);
              } else {
                g.drawRect(p0.x, p0.y, alloc.width - 1, p0.height - 1);
                g.drawRect(alloc.x, p0.y + p0.height, alloc.width - 1, r0.y - p0.y - p0.height - 1);

                if (r1.y != p1.y) {
                  g.drawRect(r1.x, r1.y, alloc.width, r1.height - 1);
                }
                g.drawRect(r1.x, p1.y, p1.x, r1.height - 1);
              }
            }

            if (filled) {
              g.fillRect(alloc.x, r0.y, alloc.width, r1.y - r0.y);
            } else {
              g.drawRect(alloc.x, r0.y, alloc.width - 1, r1.y - r0.y - 1);
            }
          } else {
            /* This part of the code has been copied (for the filling) from DefaultHighlighter.java */
            int w = alloc.x + alloc.width - p0.x;
            if (filled) {
              g.fillRect(p0.x, p0.y, w, p0.height);
              if ((p0.y + p0.height) != p1.y) {
                g.fillRect(alloc.x, p0.y + p0.height, alloc.width, p1.y - (p0.y + p0.height));
              }
              g.fillRect(alloc.x, p1.y, (p1.x - alloc.x), p1.height);
            } else {
              g.drawRect(p0.x, p0.y, w - 1, p0.height - 1);
              if ((p0.y + p0.height) != p1.y) {
                g.drawRect(
                    alloc.x, p0.y + p0.height, alloc.width - 1, p1.y - (p0.y + p0.height) - 1);
              }
              g.drawRect(alloc.x, p1.y, (p1.x - alloc.x) - 1, p1.height - 1);
            }
          }
        }
      } catch (BadLocationException e) {
      }
    }
예제 #24
0
파일: TreeUtil.java 프로젝트: jexp/idea2
  public static ActionCallback showAndSelect(
      final JTree tree,
      int top,
      int bottom,
      final int row,
      final int previous,
      boolean addToSelection,
      final boolean scroll) {
    final TreePath path = tree.getPathForRow(row);

    if (path == null) return new ActionCallback.Done();

    final int size = tree.getRowCount();
    if (size == 0) {
      tree.clearSelection();
      return new ActionCallback.Done();
    }
    if (top < 0) {
      top = 0;
    }
    if (bottom >= size) {
      bottom = size - 1;
    }

    if (row >= tree.getRowCount()) return new ActionCallback.Done();

    if (!tree.isValid()) {
      tree.validate();
    }

    final Rectangle rowBounds = tree.getRowBounds(row);
    if (rowBounds == null) return new ActionCallback.Done();

    Rectangle topBounds = tree.getRowBounds(top);
    if (topBounds == null) {
      topBounds = rowBounds;
    }

    Rectangle bottomBounds = tree.getRowBounds(bottom);
    if (bottomBounds == null) {
      bottomBounds = rowBounds;
    }

    Rectangle bounds = topBounds.union(bottomBounds);
    bounds.x = rowBounds.x;
    bounds.width = rowBounds.width;

    final Rectangle visible = tree.getVisibleRect();
    if (visible.contains(bounds)) {
      bounds = null;
    } else {
      final Component comp =
          tree.getCellRenderer()
              .getTreeCellRendererComponent(
                  tree, path.getLastPathComponent(), true, true, false, row, false);

      if (comp instanceof SimpleColoredComponent) {
        final SimpleColoredComponent renderer = ((SimpleColoredComponent) comp);
        final Dimension scrollableSize = renderer.computePreferredSize(true);
        bounds.width = scrollableSize.width;
      }
    }

    final ActionCallback callback = new ActionCallback();

    if (!tree.isRowSelected(row)) {
      if (addToSelection) {
        tree.getSelectionModel().addSelectionPath(tree.getPathForRow(row));
      } else {
        tree.setSelectionRow(row);
      }
    }

    if (bounds != null) {
      final Range<Integer> range = getExpandControlRange(tree, path);
      if (range != null) {
        int delta = bounds.x - range.getFrom().intValue();
        bounds.x -= delta;
        bounds.width -= delta;
      }

      if (visible.width < bounds.width) {
        bounds.width = visible.width;
      }

      final Rectangle b1 = bounds;
      final Runnable runnable =
          new Runnable() {
            public void run() {
              if (scroll) {
                tree.scrollRectToVisible(b1);
              }
              callback.setDone();
            }
          };

      if (ApplicationManager.getApplication().isUnitTestMode()) {
        runnable.run();
      } else {
        SwingUtilities.invokeLater(runnable);
      }
    } else {
      callback.setDone();
    }

    return callback;
  }
예제 #25
0
  /**
   * Compute and return the location of the icons origin, the location of origin of the text
   * baseline, and a possibly clipped version of the compound labels string. Locations are computed
   * relative to the viewR rectangle.
   */
  private static String layoutMenuItem(
      JComponent c,
      FontMetrics fm,
      String text,
      FontMetrics fmAccel,
      String acceleratorText,
      Icon icon,
      Icon checkIcon,
      Icon arrowIcon,
      int verticalAlignment,
      int horizontalAlignment,
      int verticalTextPosition,
      int horizontalTextPosition,
      Rectangle viewR,
      Rectangle iconR,
      Rectangle textR,
      Rectangle acceleratorR,
      Rectangle checkIconR,
      Rectangle arrowIconR,
      int textIconGap,
      int menuItemGap) {

    SwingUtilities.layoutCompoundLabel(
        c,
        fm,
        text,
        icon,
        verticalAlignment,
        horizontalAlignment,
        verticalTextPosition,
        horizontalTextPosition,
        viewR,
        iconR,
        textR,
        textIconGap);

    /* Initialize the acceelratorText bounds rectangle textR.  If a null
     * or and empty String was specified we substitute "" here
     * and use 0,0,0,0 for acceleratorTextR.
     */
    if ((acceleratorText == null) || acceleratorText.equals("")) {
      acceleratorR.width = acceleratorR.height = 0;
      acceleratorText = "";
    } else {
      acceleratorR.width = SwingUtilities2.stringWidth(c, fmAccel, acceleratorText);
      acceleratorR.height = fmAccel.getHeight();
    }

    /* Initialize the checkIcon bounds rectangle checkIconR.
     */

    if (checkIcon != null) {
      checkIconR.width = checkIcon.getIconWidth();
      checkIconR.height = checkIcon.getIconHeight();
    } else {
      checkIconR.width = checkIconR.height = 0;
    }

    /* Initialize the arrowIcon bounds rectangle arrowIconR.
     */

    if (arrowIcon != null) {
      arrowIconR.width = arrowIcon.getIconWidth();
      arrowIconR.height = arrowIcon.getIconHeight();
    } else {
      arrowIconR.width = arrowIconR.height = 0;
    }

    Rectangle labelR = iconR.union(textR);
    if (MotifGraphicsUtils.isLeftToRight(c)) {
      textR.x += checkIconR.width + menuItemGap;
      iconR.x += checkIconR.width + menuItemGap;

      // Position the Accelerator text rect
      acceleratorR.x = viewR.x + viewR.width - arrowIconR.width - menuItemGap - acceleratorR.width;

      // Position the Check and Arrow Icons
      checkIconR.x = viewR.x;
      arrowIconR.x = viewR.x + viewR.width - menuItemGap - arrowIconR.width;
    } else {
      textR.x -= (checkIconR.width + menuItemGap);
      iconR.x -= (checkIconR.width + menuItemGap);

      // Position the Accelerator text rect
      acceleratorR.x = viewR.x + arrowIconR.width + menuItemGap;

      // Position the Check and Arrow Icons
      checkIconR.x = viewR.x + viewR.width - checkIconR.width;
      arrowIconR.x = viewR.x + menuItemGap;
    }

    // Align the accelertor text and the check and arrow icons vertically
    // with the center of the label rect.
    acceleratorR.y = labelR.y + (labelR.height / 2) - (acceleratorR.height / 2);
    arrowIconR.y = labelR.y + (labelR.height / 2) - (arrowIconR.height / 2);
    checkIconR.y = labelR.y + (labelR.height / 2) - (checkIconR.height / 2);

    /*
    System.out.println("Layout: v=" +viewR+"  c="+checkIconR+" i="+
    iconR+" t="+textR+" acc="+acceleratorR+" a="+arrowIconR);
    */
    return text;
  }
  /**
   * invoked by reflection
   *
   * @param dataManager
   * @param applicationInfoEx
   * @param actionManager
   * @param uiSettings
   */
  public WindowManagerImpl(
      DataManager dataManager,
      ApplicationInfoEx applicationInfoEx,
      ActionManagerEx actionManager,
      UISettings uiSettings,
      MessageBus bus) {
    myApplicationInfoEx = applicationInfoEx;
    myDataManager = dataManager;
    myActionManager = actionManager;
    myUiSettings = uiSettings;
    if (myDataManager instanceof DataManagerImpl) {
      ((DataManagerImpl) myDataManager).setWindowManager(this);
    }

    final Application application = ApplicationManager.getApplication();
    if (!application.isUnitTestMode()) {
      Disposer.register(
          application,
          new Disposable() {
            @Override
            public void dispose() {
              disposeRootFrame();
            }
          });
    }

    myCommandProcessor = new CommandProcessor();
    myWindowWatcher = new WindowWatcher();
    final KeyboardFocusManager keyboardFocusManager =
        KeyboardFocusManager.getCurrentKeyboardFocusManager();
    keyboardFocusManager.addPropertyChangeListener(FOCUSED_WINDOW_PROPERTY_NAME, myWindowWatcher);
    if (Patches.SUN_BUG_ID_4218084) {
      keyboardFocusManager.addPropertyChangeListener(
          FOCUSED_WINDOW_PROPERTY_NAME, new SUN_BUG_ID_4218084_Patch());
    }
    myLayout = new DesktopLayout();
    myProject2Frame = new HashMap<Project, IdeFrameImpl>();
    myDialogsToDispose = new HashMap<Project, Set<JDialog>>();
    myFrameExtendedState = Frame.NORMAL;

    // Calculate screen bounds.

    Rectangle screenBounds = new Rectangle();
    if (!application.isHeadlessEnvironment()) {
      final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
      final GraphicsDevice[] devices = env.getScreenDevices();
      for (final GraphicsDevice device : devices) {
        screenBounds = screenBounds.union(device.getDefaultConfiguration().getBounds());
      }
    }
    myScreenBounds = screenBounds;

    myActivationListener =
        new WindowAdapter() {
          public void windowActivated(WindowEvent e) {
            Window activeWindow = e.getWindow();
            if (activeWindow instanceof IdeFrameImpl) { // must be
              proceedDialogDisposalQueue(((IdeFrameImpl) activeWindow).getProject());
            }
          }
        };

    bus.connect()
        .subscribe(
            AppLifecycleListener.TOPIC,
            new AppLifecycleListener.Adapter() {
              @Override
              public void appClosing() {
                // save fullscreen window states
                if (isFullScreenSupportedInCurrentOS()
                    && GeneralSettings.getInstance().isReopenLastProject()) {
                  Project[] openProjects = ProjectManager.getInstance().getOpenProjects();

                  if (openProjects.length > 0) {
                    WindowManagerEx wm = WindowManagerEx.getInstanceEx();
                    for (Project project : openProjects) {
                      IdeFrameImpl frame = wm.getFrame(project);
                      if (frame != null) {
                        frame.storeFullScreenStateIfNeeded();
                      }
                    }
                  }
                }
              }
            });

    if (UIUtil.hasLeakingAppleListeners()) {
      UIUtil.addAwtListener(
          new AWTEventListener() {
            @Override
            public void eventDispatched(AWTEvent event) {
              if (event.getID() == ContainerEvent.COMPONENT_ADDED) {
                if (((ContainerEvent) event).getChild() instanceof JViewport) {
                  UIUtil.removeLeakingAppleListeners();
                }
              }
            }
          },
          AWTEvent.CONTAINER_EVENT_MASK,
          application);
    }
  }
  public static Dimension getPreferredSize(AbstractButton b) {
    String style = (String) b.getClientProperty("Quaqua.Button.style");
    if (style == null) {
      style = "push";
    }
    if (style.equals("help")) {
      Icon helpIcon = UIManager.getIcon("Button.helpIcon");
      Insets insets = b.getInsets();

      return new Dimension(
          helpIcon.getIconWidth() + insets.left + insets.right,
          helpIcon.getIconHeight() + insets.top + insets.bottom);
    }
    if (b.getComponentCount() > 0) {
      return null;
    }

    int textIconGap = Methods.invokeGetter(b, "getIconTextGap", 4);
    Icon icon = (Icon) b.getIcon();
    String text = b.getText();

    Font font = b.getFont();
    FontMetrics fm = b.getFontMetrics(font);

    viewR.x = viewR.y = 0;
    viewR.width = Short.MAX_VALUE;
    viewR.height = Short.MAX_VALUE;
    iconR.x = iconR.y = iconR.width = iconR.height = 0;
    textR.x = textR.y = textR.width = textR.height = 0;

    SwingUtilities.layoutCompoundLabel(
        (JComponent) b,
        fm,
        text,
        icon,
        b.getVerticalAlignment(),
        b.getHorizontalAlignment(),
        b.getVerticalTextPosition(),
        b.getHorizontalTextPosition(),
        viewR,
        iconR,
        textR,
        (text == null ? 0 : textIconGap));

    /* The preferred size of the button is the size of
     * the text and icon rectangles plus the buttons insets.
     */

    Rectangle r = iconR.union(textR);

    // if (b.isBorderPainted()) {
    Insets insets = b.getInsets();
    r.width += insets.left + insets.right;
    r.height += insets.top + insets.bottom;
    // }
    if (!QuaquaUtilities.isSmallSizeVariant(b)
        && style.equals("push")
        && b.getIcon() == null
        && b.getText() != null) {
      r.width = Math.max(r.width, UIManager.getInt("Button.minimumWidth"));
    }
    return r.getSize();
  }
예제 #28
0
  /**
   * Presents a dialog to the user for selecting a print service (printer). It is displayed at the
   * location specified by the application and is modal. If the specification is invalid or would
   * make the dialog not visible it will be displayed at a location determined by the
   * implementation. The dialog blocks its calling thread and is application modal.
   *
   * <p>The dialog may include a tab panel with custom UI lazily obtained from the PrintService's
   * ServiceUIFactory when the PrintService is browsed. The dialog will attempt to locate a
   * MAIN_UIROLE first as a JComponent, then as a Panel. If there is no ServiceUIFactory or no
   * matching role the custom tab will be empty or not visible.
   *
   * <p>The dialog returns the print service selected by the user if the user OK's the dialog and
   * null if the user cancels the dialog.
   *
   * <p>An application must pass in an array of print services to browse. The array must be non-null
   * and non-empty. Typically an application will pass in only PrintServices capable of printing a
   * particular document flavor.
   *
   * <p>An application may pass in a PrintService to be initially displayed. A non-null parameter
   * must be included in the array of browsable services. If this parameter is null a service is
   * chosen by the implementation.
   *
   * <p>An application may optionally pass in the flavor to be printed. If this is non-null choices
   * presented to the user can be better validated against those supported by the services. An
   * application must pass in a PrintRequestAttributeSet for returning user choices. On calling the
   * PrintRequestAttributeSet may be empty, or may contain application-specified values.
   *
   * <p>These are used to set the initial settings for the initially displayed print service. Values
   * which are not supported by the print service are ignored. As the user browses print services,
   * attributes and values are copied to the new display. If a user browses a print service which
   * does not support a particular attribute-value, the default for that service is used as the new
   * value to be copied.
   *
   * <p>If the user cancels the dialog, the returned attributes will not reflect any changes made by
   * the user.
   *
   * <p>A typical basic usage of this method may be :
   *
   * <pre>{@code
   * PrintService[] services = PrintServiceLookup.lookupPrintServices(
   *                            DocFlavor.INPUT_STREAM.JPEG, null);
   * PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
   * if (services.length > 0) {
   *    PrintService service =  ServiceUI.printDialog(null, 50, 50,
   *                                               services, services[0],
   *                                               null,
   *                                               attributes);
   *    if (service != null) {
   *     ... print ...
   *    }
   * }
   * }</pre>
   *
   * <p>
   *
   * @param gc used to select screen. null means primary or default screen.
   * @param x location of dialog including border in screen coordinates
   * @param y location of dialog including border in screen coordinates
   * @param services to be browsable, must be non-null.
   * @param defaultService - initial PrintService to display.
   * @param flavor - the flavor to be printed, or null.
   * @param attributes on input is the initial application supplied preferences. This cannot be null
   *     but may be empty. On output the attributes reflect changes made by the user.
   * @return print service selected by the user, or null if the user cancelled the dialog.
   * @throws HeadlessException if GraphicsEnvironment.isHeadless() returns true.
   * @throws IllegalArgumentException if services is null or empty, or attributes is null, or the
   *     initial PrintService is not in the list of browsable services.
   */
  public static PrintService printDialog(
      GraphicsConfiguration gc,
      int x,
      int y,
      PrintService[] services,
      PrintService defaultService,
      DocFlavor flavor,
      PrintRequestAttributeSet attributes)
      throws HeadlessException {
    int defaultIndex = -1;

    if (GraphicsEnvironment.isHeadless()) {
      throw new HeadlessException();
    } else if ((services == null) || (services.length == 0)) {
      throw new IllegalArgumentException("services must be non-null " + "and non-empty");
    } else if (attributes == null) {
      throw new IllegalArgumentException("attributes must be non-null");
    }

    if (defaultService != null) {
      for (int i = 0; i < services.length; i++) {
        if (services[i].equals(defaultService)) {
          defaultIndex = i;
          break;
        }
      }

      if (defaultIndex < 0) {
        throw new IllegalArgumentException("services must contain " + "defaultService");
      }
    } else {
      defaultIndex = 0;
    }

    // For now we set owner to null. In the future, it may be passed
    // as an argument.
    Window owner = null;

    Rectangle gcBounds =
        (gc == null)
            ? GraphicsEnvironment.getLocalGraphicsEnvironment()
                .getDefaultScreenDevice()
                .getDefaultConfiguration()
                .getBounds()
            : gc.getBounds();

    ServiceDialog dialog;
    if (owner instanceof Frame) {
      dialog =
          new ServiceDialog(
              gc,
              x + gcBounds.x,
              y + gcBounds.y,
              services,
              defaultIndex,
              flavor,
              attributes,
              (Frame) owner);
    } else {
      dialog =
          new ServiceDialog(
              gc,
              x + gcBounds.x,
              y + gcBounds.y,
              services,
              defaultIndex,
              flavor,
              attributes,
              (Dialog) owner);
    }
    Rectangle dlgBounds = dialog.getBounds();

    // get union of all GC bounds
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] gs = ge.getScreenDevices();
    for (int j = 0; j < gs.length; j++) {
      gcBounds = gcBounds.union(gs[j].getDefaultConfiguration().getBounds());
    }

    // if portion of dialog is not within the gc boundary
    if (!gcBounds.contains(dlgBounds)) {
      // put in the center relative to parent frame/dialog
      dialog.setLocationRelativeTo(owner);
    }
    dialog.show();

    if (dialog.getStatus() == ServiceDialog.APPROVE) {
      PrintRequestAttributeSet newas = dialog.getAttributes();
      Class dstCategory = Destination.class;
      Class amCategory = SunAlternateMedia.class;
      Class fdCategory = Fidelity.class;

      if (attributes.containsKey(dstCategory) && !newas.containsKey(dstCategory)) {
        attributes.remove(dstCategory);
      }

      if (attributes.containsKey(amCategory) && !newas.containsKey(amCategory)) {
        attributes.remove(amCategory);
      }

      attributes.addAll(newas);

      Fidelity fd = (Fidelity) attributes.get(fdCategory);
      if (fd != null) {
        if (fd == Fidelity.FIDELITY_TRUE) {
          removeUnsupportedAttributes(dialog.getPrintService(), flavor, attributes);
        }
      }
    }

    return dialog.getPrintService();
  }
예제 #29
0
  public void paint(final Graphics graphic) {
    redrawCount++;
    graphic.translate(insets.left, insets.top);
    final Rectangle paintArea = graphic.getClipBounds();
    final Rectangle layoutArea = layoutViews();
    if (layoutArea != null) {
      paintArea.union(layoutArea);
    }

    if (spy != null) {
      spy.redraw(paintArea.toString(), redrawCount);
    }
    if (UI_LOG.isDebugEnabled()) {
      UI_LOG.debug(
          "------ repaint viewer #"
              + redrawCount
              + " "
              + paintArea.x
              + ","
              + paintArea.y
              + " "
              + paintArea.width
              + "x"
              + paintArea.height);
    }

    final Canvas c = createCanvas(graphic, paintArea);
    if (background != null) {
      background.draw(c.createSubcanvas(), rootView.getSize());
    }

    // paint views
    if (rootView != null) {
      rootView.draw(c.createSubcanvas());
    }
    // paint overlay

    final Bounds bounds = overlayView.getBounds();
    if (paintArea.intersects(
        new Rectangle(bounds.getX(), bounds.getY(), bounds.getWidth(), bounds.getHeight()))) {
      overlayView.draw(c.createSubcanvas(bounds));
    }

    /*
     * for (int i = 0; i < panes.length; i++) {
     * panes[i].draw(c.createSubcanvas()); }
     */
    // paint status
    // paintUserStatus(bufferGraphics);
    // blat to screen
    if (doubleBuffering) {
      graphic.drawImage(doubleBuffer, 0, 0, null);
    }
    if (showRepaintArea) {
      graphic.setColor(
          ((AwtColor) Toolkit.getColor(ColorsAndFonts.COLOR_DEBUG_BOUNDS_REPAINT)).getAwtColor());
      graphic.drawRect(paintArea.x, paintArea.y, paintArea.width - 1, paintArea.height - 1);
      graphic.drawString("#" + redrawCount, paintArea.x + 3, paintArea.y + 15);
    }

    // paint status
    paintStatus(graphic);
  }