Example #1
0
 protected void drawImageMosaic(Graphics2D g2) {
   // Break the image up into tiles. Draw each
   //   tile with its own transparency, allowing
   //   the background to show through to varying
   //   degrees.
   int side = 36;
   int width = mImage.getWidth();
   int height = mImage.getHeight();
   for (int y = 0; y < height; y += side) {
     for (int x = 0; x < width; x += side) {
       // Calculate an appropriate transparency value.
       float xBias = (float) x / (float) width;
       float yBias = (float) y / (float) height;
       float alpha = 1.0f - Math.abs(xBias - yBias);
       g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
       // Draw the subimage.
       int w = Math.min(side, width - x);
       int h = Math.min(side, height - y);
       BufferedImage tile = mImage.getSubimage(x, y, w, h);
       g2.drawImage(tile, x, y, null);
     }
   }
   // Reset the composite.
   g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
 }
Example #2
0
  // Scaling relative to the center of the screen
  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    if (bufferImage == null) {
      bufferImage = createImage(getWidth(), getHeight());
      bufferg = (Graphics2D) bufferImage.getGraphics();

      updateAffineTransform();
      preSize = getSize();
    }
    bufferg.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    bufferg.setTransform(new AffineTransform());
    bufferg.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
    bufferg.setColor(Color.WHITE);
    bufferg.fillRect(0, 0, getWidth(), getHeight());

    bufferg.setTransform(affineTransform);

    Graphics2D g2d = bufferg;

    if (ORIPA.doc.hasModel) {
      g2d.setStroke(Config.STROKE_CUT);
      if (Globals.modelDispMode == Constants.ModelDispMode.FILL_ALPHA) {
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f));
      }
      drawModel(g2d);
      g.drawImage(bufferImage, 0, 0, this);
    }
  }
Example #3
0
  private void paintVisibleWindow(Graphics2D g) {
    Rectangle visibleArea = editor.getScrollingModel().getVisibleArea();
    int firstVisibleLine = getMapYFromEditorY((int) visibleArea.getMinY());
    int height =
        coords.linesToPixels(
            (int) ((visibleArea.getMaxY() - visibleArea.getMinY()) / editor.getLineHeight()));

    // Draw the current viewport
    g.setColor(viewportColor);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f));
    g.drawRect(0, firstVisibleLine, getWidth(), height);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.20f));
    g.fillRect(0, firstVisibleLine, getWidth(), height);
  }
    @Override
    protected void paintComponent(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;

      final Dimension size = getSize();
      int _size = Math.min(size.width, size.height);
      _size = Math.min(_size, 600);

      if (myImage != null && myShouldInvalidate) {
        if (myImage.getWidth(null) != _size) {
          myImage = null;
        }
      }

      myShouldInvalidate = false;

      if (myImage == null) {
        myImage =
            createImage(
                new ColorWheelImageProducer(
                    _size - BORDER_SIZE * 2, _size - BORDER_SIZE * 2, myBrightness));
        myWheel =
            new Rectangle(
                BORDER_SIZE, BORDER_SIZE, _size - BORDER_SIZE * 2, _size - BORDER_SIZE * 2);
      }

      g.setColor(UIManager.getColor("Panel.background"));
      g.fillRect(0, 0, getWidth(), getHeight());

      g2d.setComposite(
          AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ((float) myOpacity) / 255f));
      g.drawImage(myImage, myWheel.x, myWheel.y, null);

      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f));

      int mx = myWheel.x + myWheel.width / 2;
      int my = myWheel.y + myWheel.height / 2;
      //noinspection UseJBColor
      g.setColor(Color.WHITE);
      int arcw = (int) (myWheel.width * mySaturation / 2);
      int arch = (int) (myWheel.height * mySaturation / 2);
      double th = myHue * 2 * Math.PI;
      final int x = (int) (mx + arcw * Math.cos(th));
      final int y = (int) (my - arch * Math.sin(th));
      g.fillRect(x - 2, y - 2, 4, 4);
      //noinspection UseJBColor
      g.setColor(Color.BLACK);
      g.drawRect(x - 2, y - 2, 4, 4);
    }
Example #5
0
 @Override
 public void paintIcon(Component c, Graphics g, int x, int y) {
   Graphics2D g2 = (Graphics2D) g.create();
   g2.setPaint(Objects.nonNull(c) ? c.getBackground() : Color.WHITE);
   g2.fillRect(x, y, getIconWidth(), getIconHeight());
   g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
   g2.setColor(ELLIPSE_COLOR);
   g2.translate(x, y);
   int size = list.size();
   for (int i = 0; i < size; i++) {
     float alpha = isRunning ? (i + 1) / (float) size : .5f;
     g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
     g2.fill(list.get(i));
   }
   // g2.translate(-x, -y);
   g2.dispose();
 }
  // Takes resource name and returns button
  public JButton createButton(String name, String toolTip) {

    // load the image
    String imagePath = "./resources/" + name + ".png";
    ImageIcon iconRollover = new ImageIcon(imagePath);
    int w = iconRollover.getIconWidth();
    int h = iconRollover.getIconHeight();

    // get the cursor for this button
    Cursor cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);

    // make translucent default image
    Image image = createCompatibleImage(w, h, Transparency.TRANSLUCENT);
    Graphics2D g = (Graphics2D) image.getGraphics();
    Composite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);
    g.setComposite(alpha);
    g.drawImage(iconRollover.getImage(), 0, 0, null);
    g.dispose();
    ImageIcon iconDefault = new ImageIcon(image);

    // make a pressed image
    image = createCompatibleImage(w, h, Transparency.TRANSLUCENT);
    g = (Graphics2D) image.getGraphics();
    g.drawImage(iconRollover.getImage(), 2, 2, null);
    g.dispose();
    ImageIcon iconPressed = new ImageIcon(image);

    // create the button
    JButton button = new JButton();
    button.addActionListener(this);
    button.setIgnoreRepaint(true);
    button.setFocusable(false);
    button.setToolTipText(toolTip);
    button.setBorder(null);
    button.setContentAreaFilled(false);
    button.setCursor(cursor);
    button.setIcon(iconDefault);
    button.setRolloverIcon(iconRollover);
    button.setPressedIcon(iconPressed);

    return button;
  }
  @Override
  public void draw(Graphics2D g) {
    double opacity = get(OPACITY);
    opacity = Math.min(Math.max(0d, opacity), 1d);
    if (opacity != 0d) {
      if (opacity != 1d) {
        Rectangle2D.Double drawingArea = getDrawingArea();

        Rectangle2D clipBounds = g.getClipBounds();
        if (clipBounds != null) {
          Rectangle2D.intersect(drawingArea, clipBounds, drawingArea);
        }

        if (!drawingArea.isEmpty()) {

          BufferedImage buf =
              new BufferedImage(
                  (int) ((2 + drawingArea.width) * g.getTransform().getScaleX()),
                  (int) ((2 + drawingArea.height) * g.getTransform().getScaleY()),
                  BufferedImage.TYPE_INT_ARGB);
          Graphics2D gr = buf.createGraphics();
          gr.scale(g.getTransform().getScaleX(), g.getTransform().getScaleY());
          gr.translate((int) -drawingArea.x, (int) -drawingArea.y);
          gr.setRenderingHints(g.getRenderingHints());
          drawFigure(gr);
          gr.dispose();
          Composite savedComposite = g.getComposite();
          g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) opacity));
          g.drawImage(
              buf,
              (int) drawingArea.x,
              (int) drawingArea.y,
              2 + (int) drawingArea.width,
              2 + (int) drawingArea.height,
              null);
          g.setComposite(savedComposite);
        }
      } else {
        drawFigure(g);
      }
    }
  }
Example #8
0
  private void paintSelection(Graphics2D g) {
    int selectionStartOffset = editor.getSelectionModel().getSelectionStart();
    int selectionEndOffset = editor.getSelectionModel().getSelectionEnd();
    int firstSelectedLine = coords.offsetToScreenSpace(selectionStartOffset);
    int firstSelectedCharacter = coords.offsetToCharacterInLine(selectionStartOffset);
    int lastSelectedLine = coords.offsetToScreenSpace(selectionEndOffset);
    int lastSelectedCharacter = coords.offsetToCharacterInLine(selectionEndOffset);

    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.90f));
    g.setColor(
        editor
            .getColorsScheme()
            .getColor(ColorKey.createColorKey("SELECTION_BACKGROUND", JBColor.BLUE)));

    if (firstSelectedLine == lastSelectedLine) {
      // Single line is easy
      g.fillRect(
          firstSelectedCharacter,
          firstSelectedLine,
          lastSelectedCharacter - firstSelectedCharacter,
          config.pixelsPerLine);
    } else {
      // Draw the line leading in
      g.fillRect(
          firstSelectedCharacter,
          firstSelectedLine,
          getWidth() - firstSelectedCharacter,
          config.pixelsPerLine);

      // Then the line at the end
      g.fillRect(0, lastSelectedLine, lastSelectedCharacter, config.pixelsPerLine);

      if (firstSelectedLine + 1 != lastSelectedLine) {
        // And if there is anything in between, fill it in
        g.fillRect(
            0,
            firstSelectedLine + config.pixelsPerLine,
            getWidth(),
            lastSelectedLine - firstSelectedLine - config.pixelsPerLine);
      }
    }
  }
Example #9
0
  public void drawModel(Graphics2D g2d) {
    for (OriFace face : ORIPA.doc.sortedFaces) {
      if (Globals.modelDispMode == Constants.ModelDispMode.FILL_COLOR) {
        if (face.faceFront) {
          g2d.setColor(new Color(255, 200, 200));
        } else {
          g2d.setColor(new Color(200, 200, 255));
        }
        g2d.fill(face.outline);
      } else if (Globals.modelDispMode == Constants.ModelDispMode.FILL_WHITE) {
        g2d.setColor(Color.WHITE);
        g2d.fill(face.outline);
      } else if (Globals.modelDispMode == Constants.ModelDispMode.FILL_ALPHA) {
        g2d.setColor(new Color(100, 100, 100));
        g2d.fill(face.outline);
      }

      g2d.setColor(Color.BLACK);
      for (OriHalfedge he : face.halfedges) {
        if (he.pair == null) {
          g2d.setStroke(Config.MODEL_STROKE_CUT);
        } else {
          g2d.setStroke(Config.STROKE_CUT);
        }
        g2d.draw(
            new Line2D.Double(
                he.positionForDisplay.x,
                he.positionForDisplay.y,
                he.next.positionForDisplay.x,
                he.next.positionForDisplay.y));
      }
    }

    if (Globals.bDispCrossLine) {
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
      g2d.setStroke(Config.MODEL_STROKE_CUT);
      g2d.setColor(Color.RED);

      g2d.draw(new Line2D.Double(crossLine.p0.x, crossLine.p0.y, crossLine.p1.x, crossLine.p1.y));
    }
  }
    private void updatePipette() {
      Dialog pickerDialog = getPickerDialog();
      if (pickerDialog != null && pickerDialog.isShowing()) {
        Point mouseLoc = updateLocation();
        if (mouseLoc == null) return;
        final Color c = getPixelColor(mouseLoc);
        if (!c.equals(getColor()) || !mouseLoc.equals(myPreviousLocation)) {
          setColor(c);
          myPreviousLocation.setLocation(mouseLoc);
          myCaptureRect.setBounds(
              mouseLoc.x - HOT_SPOT.x + SIZE / 2 - 2, mouseLoc.y - HOT_SPOT.y + SIZE / 2 - 2, 5, 5);

          BufferedImage capture = myRobot.createScreenCapture(myCaptureRect);

          // Clear the cursor graphics
          myGraphics.setComposite(AlphaComposite.Src);
          myGraphics.setColor(UIUtil.TRANSPARENT_COLOR);
          myGraphics.fillRect(0, 0, myImage.getWidth(), myImage.getHeight());

          myGraphics.drawImage(
              capture, myZoomRect.x, myZoomRect.y, myZoomRect.width, myZoomRect.height, this);

          // cropping round image
          myGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT));
          myGraphics.drawImage(
              myMaskImage, myZoomRect.x, myZoomRect.y, myZoomRect.width, myZoomRect.height, this);

          // paint magnifier
          myGraphics.setComposite(AlphaComposite.SrcOver);

          UIUtil.drawImage(
              myGraphics, myPipetteImage, SIZE - AllIcons.Ide.Pipette.getIconWidth(), 0, this);

          pickerDialog.setCursor(
              myParent.getToolkit().createCustomCursor(myImage, HOT_SPOT, "ColorPicker"));
          notifyListener(c, 300);
        }
      }
    }
  /**
   * Draw the icon at the specified location. Paints this component as an icon.
   *
   * @param c the component which can be used as observer
   * @param g the <tt>Graphics</tt> object used for painting
   * @param x the position on the X coordinate
   * @param y the position on the Y coordinate
   */
  public void paintIcon(Component c, Graphics g, int x, int y) {
    g = g.create();
    try {
      Graphics2D g2 = (Graphics2D) g;
      AntialiasingManager.activateAntialiasing(g2);

      g2.setColor(Color.WHITE);
      g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
      g2.fillRoundRect(x, y, getIconWidth() - 1, getIconHeight() - 1, 10, 10);
      g2.setColor(Color.DARK_GRAY);
      g2.drawRoundRect(x, y, getIconWidth() - 1, getIconHeight() - 1, 10, 10);

      // Indent component content from the border.
      g2.translate(x + 5, y + 5);

      super.paint(g2);

      g2.translate(x, y);
    } finally {
      g.dispose();
    }
  }
Example #12
0
/** Implements Panel on which you can draw cells */
public class AutomatonPanel extends JPanel {
  private static final AlphaComposite compositeGrid =
      AlphaComposite.getInstance(AlphaComposite.DST_OUT);
  private static final AlphaComposite compositeStructPreview =
      AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f);
  private static final int MAX_SCALE = 500;
  private static final double MIN_SCALE = 0.01;
  private static final double SHOW_GRID_MIN_SCALE = 2;
  private static final int BORDER_WIDTH = 2;
  private static final Color BORDER_COLOR = Color.GRAY;
  final Object LOCKER = new Object();
  private final AffineTransform transformCells = new AffineTransform();
  private final AffineTransform transformGrid = new AffineTransform();
  private BufferedImage bufferedImage, bufferedImageGrid;
  private int[] pixels;
  private double previousX;
  private double previousY;
  private double zoomCenterX;
  private double zoomCenterY;

  private BufferedImage structurePreview = null;
  private Point2D previewPoint = null;
  private AffineTransform previewTransform = null;
  private double previewRotation = 0;
  private int cellWidth;
  private int cellHeight;

  public AutomatonPanel() {
    setDoubleBuffered(true);
    setBackground(Color.BLACK);
    setOpaque(false);

    initListeners();
  }

  private void initListeners() {
    addMouseListener(
        new MouseAdapter() {
          public void mousePressed(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
              previousX = e.getX();
              previousY = e.getY();
            }
          }
        });
    addMouseMotionListener(
        new MouseMotionAdapter() {
          public void mouseDragged(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
              transformGrid.translate(e.getX() - previousX, e.getY() - previousY);

              Point2D adjPreviousPoint = getTranslatedPoint(previousX, previousY);
              Point2D adjNewPoint = getTranslatedPoint(e.getX(), e.getY());

              double newX = adjNewPoint.getX() - adjPreviousPoint.getX();
              double newY = adjNewPoint.getY() - adjPreviousPoint.getY();

              previousX = e.getX();
              previousY = e.getY();

              transformCells.translate(newX, newY);
              calculateGridTranslation();

              repaint();
            }
          }
        });
    addMouseWheelListener(
        e -> {
          if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
            Point2D point2D = getTranslatedPoint(e.getPoint().getX(), e.getPoint().getY());
            zoomCenterX = point2D.getX();
            zoomCenterY = point2D.getY();
            handleZoom(e.getPreciseWheelRotation());
          }
        });

    addComponentListener(
        new ComponentListener() {
          @Override
          public void componentResized(ComponentEvent e) {
            if (bufferedImage != null) {
              bufferedImageGrid = createGrid();
              repaint();
            } else {
              // init plane with default settings
              createBufferedImage(
                  new AutomatonSettings().getWidth(), new AutomatonSettings().getHeight());
              repaint();
            }
          }

          @Override
          public void componentMoved(ComponentEvent e) {}

          @Override
          public void componentShown(ComponentEvent e) {}

          @Override
          public void componentHidden(ComponentEvent e) {}
        });
  }

  private void calculateGridTranslation() {
    if (transformCells.getScaleX() >= SHOW_GRID_MIN_SCALE) {
      @SuppressWarnings("SuspiciousNameCombination")
      double modX = Math.floorMod(round(transformCells.getTranslateX()), cellWidth);
      double modY = Math.floorMod(round(transformCells.getTranslateY()), cellHeight);
      transformGrid.setToTranslation(-cellWidth + modX - 1, -cellHeight + modY - 1);
    }
  }

  private Point2D calculateInsertionPoint(Point2D point) {
    Point2D translatedPoint = getTranslatedPoint(point.getX(), point.getY());
    // jumping
    double x = translatedPoint.getX() % 1;
    double y = translatedPoint.getY() % 1;
    if (x >= 1 / 2d) {
      x = 1 - x;
    } else {
      x = -x;
    }
    if (y >= 1 / 2d) {
      y = 1 - y;
    } else {
      y = -y;
    }

    x += translatedPoint.getX();
    y += translatedPoint.getY();
    return new Point2D.Double(x, y);
  }

  private void calculatePreviewTranslation() {
    Point2D point = calculateInsertionPoint(previewPoint);
    previewTransform = (AffineTransform) transformCells.clone();
    previewTransform.translate(point.getX(), point.getY());
    previewTransform.rotate(previewRotation, 0, 0);
  }

  @Override
  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = ((Graphics2D) g);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g2d.setRenderingHint(
        RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
    g2d.setRenderingHint(
        RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
    g2d.setRenderingHint(
        RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
    g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
    g2d.setColor(Color.BLACK);
    g2d.fillRect(0, 0, getWidth(), getHeight());

    if (bufferedImage != null) {
      synchronized (LOCKER) {
        g2d.drawImage(bufferedImage, transformCells, null);
      }
    }
    // draw struct preview
    if (structurePreview != null) {
      Composite composite = g2d.getComposite();
      g2d.setComposite(compositeStructPreview);
      g2d.drawImage(structurePreview, previewTransform, null);
      g2d.setComposite(composite);
    }
    // draw grid
    if (transformCells.getScaleX() > SHOW_GRID_MIN_SCALE) {
      Composite composite = g2d.getComposite();
      g2d.setComposite(compositeGrid);
      g2d.drawImage(bufferedImageGrid, transformGrid, null);
      g2d.setComposite(composite);
    }
    // draw border for preview
    if (structurePreview != null && Math.abs(transformCells.getScaleX()) >= 0.95) {
      Shape shape = new Rectangle(0, 0, structurePreview.getWidth(), structurePreview.getHeight());
      shape = previewTransform.createTransformedShape(shape);
      g2d.setColor(Color.RED);
      g2d.draw(shape);
    }

    // draw border
    double x = transformCells.getTranslateX();
    double y = transformCells.getTranslateY();

    g2d.setColor(BORDER_COLOR);
    g2d.setStroke(new BasicStroke(BORDER_WIDTH));
    g2d.drawRect(
        round(x - BORDER_WIDTH),
        round(y - BORDER_WIDTH),
        round(getAutomatonWidth() * transformCells.getScaleX() + 2 * BORDER_WIDTH),
        round(getAutomatonHeight() * transformCells.getScaleY() + 2 * BORDER_WIDTH));
  }

  int[] getPixelsForDrawing() {
    return pixels;
  }

  private BufferedImage createGrid() {
    if (transformCells.getScaleY() < SHOW_GRID_MIN_SCALE) {
      return null;
    }

    Point2D cellSize = getCellSizeAfterScale();
    cellWidth = round(cellSize.getX());
    cellHeight = round(cellSize.getY());

    BufferedImage image =
        new BufferedImage(
            getWidth() + 2 * (cellWidth),
            getHeight() + 2 * (cellHeight),
            BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics2D = image.createGraphics();
    graphics2D.setColor(new Color(0, true));
    graphics2D.fillRect(0, 0, image.getWidth(), image.getHeight());

    graphics2D.setPaint(Color.YELLOW);
    graphics2D.setStroke(new BasicStroke(1));

    for (int x = 0; x < image.getWidth(); x += cellWidth) {
      graphics2D.drawLine(x, 0, x, image.getHeight());
    }
    for (int y = 0; y < image.getHeight(); y += cellHeight) {
      graphics2D.drawLine(0, y, image.getWidth(), y);
    }
    transformGrid.setToIdentity();
    calculateGridTranslation();

    graphics2D.dispose();
    return image;
  }

  private Point2D getCellSizeAfterScale() {
    return new Point2D.Double(round(transformCells.getScaleX()), round(transformCells.getScaleY()));
  }

  void createBufferedImage(final int width, final int height) {
    if (bufferedImage != null
        && bufferedImage.getWidth() == width
        && bufferedImage.getHeight() == height) {
      // just clear
      clearPlane();
      return;
    }

    bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();
    previewRotation = 0;

    transformCells.setToIdentity();
    transformGrid.setToIdentity();
    // center plane if needed
    if (width < getWidth()) transformCells.translate(round((getWidth() - width) / 2f), 0);
    if (height < getHeight()) transformCells.translate(0, round((getHeight() - height) / 2f));

    bufferedImageGrid = createGrid();
  }

  private void clearPlane() {
    int black = Color.BLACK.getRGB();
    synchronized (LOCKER) {
      for (int i = 0; i < pixels.length; i++) {
        pixels[i] = black;
      }
    }
  }

  private int getAutomatonWidth() {
    return bufferedImage == null ? 0 : bufferedImage.getWidth();
  }

  private int getAutomatonHeight() {
    return bufferedImage == null ? 0 : bufferedImage.getHeight();
  }

  private Point2D getTranslatedPoint(double x, double y) {

    return getTranslatedPoint(x, y, transformCells);
  }

  private Point2D getTranslatedPoint(double x, double y, AffineTransform matrix) {

    Point2D point2d = new Point2D.Double(x, y);
    try {
      return matrix.inverseTransform(point2d, null);
    } catch (NoninvertibleTransformException ex) {
      ex.printStackTrace();
      return point2d;
    }
  }

  private int round(double number) {
    return (int) Math.round(number);
  }

  private void handleZoom(double zoom) {
    final int scaleFactor = 1;
    final double accelerationFactor = 0.05;
    final double scaleZoom = 0.25;
    final double scaleFactorDown = 0.8;

    zoom = scaleZoom * -zoom;
    zoom += 1;

    transformCells.translate(zoomCenterX, zoomCenterY);
    double newScale = transformCells.getScaleX();

    int acceleration = round(newScale * accelerationFactor);
    if (zoom > 1) {
      if (transformCells.getScaleX() > 0.95) {
        newScale = (newScale + scaleFactor + acceleration) / newScale;
      } else {
        newScale = 1 / scaleFactorDown;
      }
    } else if (zoom < 1) {
      if (transformCells.getScaleX() > 1.05) {
        newScale = (newScale - scaleFactor - acceleration) / newScale;
      } else {
        newScale = scaleFactorDown;
      }
    }

    if (transformCells.getScaleX() * newScale >= MIN_SCALE
        && transformCells.getScaleX() * newScale <= MAX_SCALE) {
      transformCells.scale(newScale, newScale);
    }
    transformCells.translate(-zoomCenterX, -zoomCenterY);

    if (previewTransform != null) {
      calculatePreviewTranslation();
    }

    bufferedImageGrid = createGrid();
    repaint();
  }

  /**
   * @param structurePreview Buffered image of structure preview
   * @param point Preview point relative to this panel
   */
  public void setStructurePreview(BufferedImage structurePreview, Point point) {
    previewPoint = point;
    this.structurePreview = structurePreview;
    calculatePreviewTranslation();
    repaint();
  }

  /** Disables structure preview */
  public void disableStructurePreview() {
    this.structurePreview = null;
    this.previewTransform = null;
    previewRotation = 0;
    repaint();
  }

  private void loopRotation() {
    if (previewRotation < 0) {
      previewRotation = Math.toRadians(270);
    } else if (previewRotation >= 2 * Math.PI) {
      previewRotation = 0;
    }
    if (structurePreview.getWidth() == 1 && structurePreview.getHeight() == 1) {
      previewRotation = 0;
    }
  }

  /** Rotates struct preview by -90 degrees */
  public void rotateStructPreviewLeft() {
    previewRotation += Math.toRadians(-90);
    loopRotation();
    calculatePreviewTranslation();
    repaint();
  }
  /** Rotates struct preview by 90 degrees */
  public void rotateStructPreviewRight() {
    previewRotation += Math.toRadians(90);
    loopRotation();
    calculatePreviewTranslation();
    repaint();
  }

  /** @return Current rotation fo structure */
  public double getStructRotation() {
    return previewRotation;
  }

  /**
   * @param point Point relative to this panel
   * @return Point relative to automaton coordinates
   */
  public Point2D getStructInsertionPoint(Point point) {
    return calculateInsertionPoint(point);
  }
}
Example #13
0
  public synchronized void paint(Graphics graphics) {

    Graphics2D g = (Graphics2D) graphics;

    Image water = Toolkit.getDefaultToolkit().getImage("catanui/water.jpg");
    g.drawImage(water, 0, 0, this);

    for (Hex o : _hexes) {
      o.paint(g, _display_offset[0], _display_offset[1]);
    }

    g.translate(_display_offset[0] + 2, _display_offset[1] - 1);
    synchronized (portContents) {
      for (Pair c : portContents.keySet()) {

        int lowx =
            hexleft
                + (((CoordPair) c.getA()).getX() - (((CoordPair) c.getA()).getX() % 2))
                    / 2
                    * intervalSide[0]
                + (((CoordPair) c.getA()).getX() - (((CoordPair) c.getA()).getX() % 2))
                    / 2
                    * intervalSide[1]
                + (((CoordPair) c.getA()).getX() % 2) * intervalSide[0];
        int lowy = hextop + ((CoordPair) c.getA()).getY() * intervalUp;
        int highx =
            hexleft
                + (((CoordPair) c.getB()).getX() - (((CoordPair) c.getB()).getX() % 2))
                    / 2
                    * intervalSide[0]
                + (((CoordPair) c.getB()).getX() - (((CoordPair) c.getB()).getX() % 2))
                    / 2
                    * intervalSide[1]
                + (((CoordPair) c.getB()).getX() % 2) * intervalSide[0];
        int highy = hextop + ((CoordPair) c.getB()).getY() * intervalUp;

        int dx = highx - lowx;
        int dy = highy - lowy;
        double rad = Math.atan((1.0) * dy / dx);

        if (dx < 0) rad += Math.PI;

        g.translate(lowx, lowy);
        g.rotate(rad);
        g.drawImage(
            BoardObject.images.get(BoardObject.type2port.get(portContents.get(c))), 0, -75, null);
        g.rotate(-rad);
        g.translate((-1) * lowx, (-1) * lowy);
      }
    }
    g.translate((-1) * _display_offset[0], (-1) * _display_offset[1]);

    synchronized (roadContents) {
      for (Pair c : roadContents.keySet()) {

        Road r =
            new Road(
                hexleft
                    + (((CoordPair) c.getA()).getX() - (((CoordPair) c.getA()).getX() % 2))
                        / 2
                        * intervalSide[0]
                    + (((CoordPair) c.getA()).getX() - (((CoordPair) c.getA()).getX() % 2))
                        / 2
                        * intervalSide[1]
                    + (((CoordPair) c.getA()).getX() % 2) * intervalSide[0],
                hextop + ((CoordPair) c.getA()).getY() * intervalUp);

        r.setX2(
            hexleft
                + (((CoordPair) c.getB()).getX() - (((CoordPair) c.getB()).getX() % 2))
                    / 2
                    * intervalSide[0]
                + (((CoordPair) c.getB()).getX() - (((CoordPair) c.getB()).getX() % 2))
                    / 2
                    * intervalSide[1]
                + (((CoordPair) c.getB()).getX() % 2) * intervalSide[0]);
        r.setY2(hextop + ((CoordPair) c.getB()).getY() * intervalUp);

        r.setColor(roadContents.get(c));
        r.paint(g, _display_offset[0], _display_offset[1]);
      }
    }

    synchronized (vertexContents) {
      for (CoordPair c : vertexContents.keySet()) {
        int newx =
            hexleft
                + ((c._x - (c._x % 2)) / 2 * intervalSide[0]
                    + (c._x - (c._x % 2)) / 2 * intervalSide[1]
                    + (c._x % 2) * intervalSide[0])
                - 20;
        int newy = hextop + c._y * intervalUp - 20;

        if ((BoardObject.type) (vertexContents.get(c).getA()) == BoardObject.type.SETTLEMENT) {
          Settlement s = new Settlement(newx, newy, (Integer) (vertexContents.get(c).getB()));
          s.paint(g, _display_offset[0], _display_offset[1]);
        } else if ((BoardObject.type) (vertexContents.get(c).getA()) == BoardObject.type.CITY) {
          City s = new City(newx, newy, (Integer) (vertexContents.get(c).getB()));
          s.paint(g, _display_offset[0], _display_offset[1]);
        } else System.out.println("neither -_-");
      }
    }

    g.setColor(Color.GRAY);
    g.fill(new Rectangle(0, 0, 110, 60));
    g.setColor(Color.LIGHT_GRAY);
    g.fill(new Rectangle(3, 3, 104, 56));
    if (_dieRoll > 0) {
      BufferedImage r1img =
          diceImage.getSubimage((int) (Math.floor((twoDice[0] - 1) * 94.7)), 0, 94, 93);
      g.drawImage(r1img, 5, 7, 48, 47, null);
      BufferedImage r2img =
          diceImage.getSubimage((int) (Math.floor((twoDice[1] - 1) * 94.7)), 0, 94, 93);
      g.drawImage(r2img, 55, 7, 48, 47, null);
    }

    if (_up != null) _up.paint(g);

    if (!_gameOver.equals("") && !_dismiss) {
      _currAlpha += 0.007;
    }
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, _currAlpha));
    g.setColor(Color.GRAY);
    g.fill(new Rectangle(-20, 0, 1020, 650));
    g.setColor(Color.BLACK);
    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) 1.0));
    if (!_gameOver.equals("")) {

      if (_currAlpha >= 0.8) {
        if (_gameOver.equals(gameLogic._name)) {
          g.drawString("Congratulations, you won!", 350, 200);
        } else {
          g.drawString(_gameOver + " has won!", 350, 200);
        }
        _dismiss = true;
      } else repaint();
    }
  }
Example #14
0
class GMap implements Serializable {

  /**
   * This class contains the modifications to the map, and is capable of generating an image at any
   * zoom level. One Gmap is shared by all the viewing panes in the GUI class.
   */

  // defaultImage
  private transient BufferedImage defaultImage;

  // transparency
  private transient AlphaComposite opacity70 =
      AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.70f);
  private transient AlphaComposite opacity40 =
      AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f);

  // google icon
  Image googleImage;

  // keep track of the data object
  private transient GDataSource gDataSourceMap;
  private transient GDataSource gDataSourceSatellite;
  private transient GDataSource gDataSourceHybrid;
  private transient GDataSource gDataSourceOverlay;

  // GDraw handles the work of painting data NOT in the database
  private GDraw gDraw;

  /** Messages */
  public static final int MESSAGE_DOWNLOADING = 0;

  public static final int MESSAGE_PAINTING = 1;

  /** Modes */
  public static final int SATELLITE_MODE = 2;

  public static final int MAP_MODE = 3;
  public static final int HYBRID_MODE = 4;
  private int mode;

  /**
   * Creates a new GMap object based on a base directory specified in the constructure.
   *
   * @param cache - Base directory to search for cached image folders.
   */
  public GMap(String cache) {
    // data source
    this.gDataSourceMap = new GDataSourceMap(cache + "/map_cache");
    this.gDataSourceSatellite = new GDataSourceSatellite(cache + "/sat_cache");
    // this.gDataSourceOverlay = new GDataSourceOverlay(cache+"/overlay_cache");
    this.gDataSourceHybrid = new GDataSourceHybrid(cache + "/hybrid_cache", gDataSourceSatellite);

    // build default image
    defaultImage = getDefaultImage(GDataSource.sourceSize.width, GDataSource.sourceSize.height);

    // init gdraw draw object
    this.gDraw = new GDraw();

    // mode
    this.mode = MAP_MODE;

    // icon
    ImageIcon loadImage = new ImageIcon("images/google.png");
    googleImage = loadImage.getImage();
  }
  /** Builds a GMap based on a 'cache' sub-directory. */
  public GMap() {
    this("cache");
  }

  // getters
  /**
   * Returns a GDataSource object used by the GMap object
   *
   * @return Returns the GDataSource used to grab the images.
   */
  public GDataSource getGDataSource() {
    return getGDataSource(mode);
  }
  /**
   * Returns a GDataSource based on a specific mode using constants: MAP_MODE, SATELLITE_MODE,
   * HYBRID_MODE
   *
   * @return A GDataSource of the specified mode.
   */
  public GDataSource getGDataSource(int mode) {
    if (mode == MAP_MODE) return gDataSourceMap;
    else if (mode == SATELLITE_MODE) return gDataSourceSatellite;
    else if (mode == HYBRID_MODE) return gDataSourceHybrid;
    return null;
  }
  /** */
  public GDraw getGDraw() {
    return gDraw;
  }
  /**
   * Gets the current used by the GMap object
   *
   * @return Current mode: MAP_MODE, SATELLITE_MODE, HYBRID_MODE
   */
  public int getMode() {
    return mode;
  }

  /**
   * Sets the current mode of the GMap object
   *
   * @param Mode to set: MAP_MODE, SATELLITE_MODE, HYBRID_MODE
   */
  public void setMode(int mode) {
    this.mode = mode;
  }

  /**
   * Sets the registered GDraw to gDraw. This method is intended primarily for serialization
   * purposes, and should not be used to modify the state of the GMap. Instead, use the GDraw's
   * public methods.
   *
   * @param gDraw
   */
  public void setGDraw(GDraw gDraw) {
    this.gDraw = gDraw;
  }

  /**
   * Method used to build image asynchronously
   *
   * @param image - Image to paint
   * @param x - x Pixel value
   * @param y - y Pixel value
   * @param w - width in pixels
   * @param h - height in pixels
   * @param cachedZoom - zoom level used
   * @param listener - GMapListener object
   */
  public void paintAsynchronousImage(
      BufferedImage image,
      int x,
      int y,
      int w,
      int h,
      int zoom,
      int cachedZoom,
      GMapListener listener) {
    buildImage(image, x, y, w, h, zoom, cachedZoom, listener);
  }
  /**
   * Returns image at x and y
   *
   * @param x - x Pixel value
   * @param y - y Pixel value
   * @param w - width in pixels
   * @param h - height in pixels
   * @param cachedZoom - zoom level used
   */
  public BufferedImage getImage(int x, int y, int w, int h, int zoom, int cachedZoom) {
    // create buffered image for return
    return getImage(x, y, w, h, zoom, cachedZoom, null);
  }
  /**
   * Returns image at x and y
   *
   * @param x - x Pixel value
   * @param y - y Pixel value
   * @param w - width in pixels
   * @param h - height in pixels
   * @param cachedZoom - zoom level used
   * @param listener - GMapListener to use in getImage
   */
  public BufferedImage getImage(
      int x, int y, int w, int h, int zoom, int cachedZoom, GMapListener listener) {
    BufferedImage toReturn = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    buildImage(toReturn, x, y, w, h, zoom, cachedZoom, listener);
    return toReturn;
  }
  /**
   * Method used to cacheImage
   *
   * @param image - Image to paint
   * @param x - x Pixel value
   * @param y - y Pixel value
   * @param w - width in pixels
   * @param h - height in pixels
   * @param zoom - zoom level used
   */
  public void cacheImage(int x, int y, int w, int h, int zoom) {
    cacheImage(x, y, w, h, zoom, null);
  }
  /**
   * Method used to cache image
   *
   * @param image - Image to paint
   * @param x - x Pixel value
   * @param y - y Pixel value
   * @param w - width in pixels
   * @param h - height in pixels
   * @param zoom - zoom level used
   */
  public void cacheImage(int x, int y, int w, int h, int zoom, GMapListener listener) {
    paintAsynchronousImage(null, x, y, w, h, zoom, (GPhysicalPoint.MIN_ZOOM - 1), listener);
  }

  /** Main method used to build the image based on a large number of tiles. */
  public void buildImage(
      BufferedImage toReturn,
      int x,
      int y,
      int w,
      int h,
      int zoom,
      int cachedZoom,
      GMapListener listener) {
    // validate
    // if(x < 0 || y < 0 || w <= 0 || h <= 0) return getDefaultImage(w,h);

    // if(toReturn != null) Graphics2D g = toReturn.createGraphics();

    // find index of point
    int xIndex = x / GDataSource.sourceSize.width;
    int yIndex = y / GDataSource.sourceSize.height;

    // find coord of our starting point
    int xCoord = x % GDataSource.sourceSize.width;
    int yCoord = y % GDataSource.sourceSize.height;

    // Checks for invalid xCoord and yCoord
    if (xCoord < 0) {
      xCoord = 0;
    }
    if (yCoord < 0) {
      yCoord = 0;
    }

    // load this index
    BufferedImage image = getIndexedImage(xIndex, yIndex, zoom, cachedZoom, listener);

    // get info about the image
    // Dimension imageSize = new Dimension(image.getWidth(),image.getHeight());

    // Holds number of row and column images needed
    int rowImages;
    int colImages;

    // find the width of what we CAN paint
    int paintWidth = GDataSource.sourceSize.width - xCoord;
    int paintHeight = GDataSource.sourceSize.height - yCoord;

    // Calculate number of row images
    if ((h - paintHeight) % 256 == 0) {
      rowImages = 1 + (h - paintHeight) / 256;
    } else {
      rowImages = 2 + (h - paintHeight) / 256;
    }

    // Calculate number of column images
    if ((w - paintWidth) % 256 == 0) {
      colImages = 1 + (w - paintWidth) / 256;
    } else {
      colImages = 2 + (w - paintWidth) / 256;
    }

    // Overal Image coordinates
    int xImage = 0;
    int yImage = 0;

    // DEBUG
    // System.out.println(x + " " + y + " " + w + " " + h + " " + rowImages + " " + colImages);
    // System.out.println();

    // set listener
    if (listener != null) listener.updateGMapTaskSize(rowImages * colImages);

    // a counter for the listener
    int completed = 0;

    // Iteratively loops through all CACHED images and paints them
    for (int row = 0; row < rowImages; row++) {
      for (int col = 0; col < colImages; col++) {
        int thisXIndex = x / GDataSource.sourceSize.width + col;
        int thisYIndex = y / GDataSource.sourceSize.height + row;

        getSpecificImage(x, y, w, h, col, row, toReturn, zoom, cachedZoom, listener, true);
        if (getGDataSource().isCached(thisXIndex, thisYIndex, zoom)) {
          if (listener != null) {
            listener.updateGMapCompleted(completed);
            completed++;
          }
        }
        if (listener.asynchronousGMapStopFlag()) return;
      }
    }

    // do the UNCACHED IMAGES NEXT
    for (int row = 0; row < rowImages; row++) {
      for (int col = 0; col < colImages; col++) {
        int thisXIndex = x / GDataSource.sourceSize.width + col;
        int thisYIndex = y / GDataSource.sourceSize.height + row;

        if (!getGDataSource().isCached(thisXIndex, thisYIndex, zoom)) {
          getSpecificImage(x, y, w, h, col, row, toReturn, zoom, cachedZoom, listener, false);
          if (listener != null) {
            listener.updateGMapCompleted(completed);
            completed++;
            if (listener.asynchronousGMapStopFlag()) return;
          }
        }
      }
    }

    // the dispatch to GDraw object
    gDraw.draw(toReturn, new GPhysicalPoint(x, y, zoom), zoom);
  }

  private BufferedImage getSpecificImage(
      int x,
      int y,
      int w,
      int h,
      int imgIndexX,
      int imgIndexY,
      BufferedImage buffImg,
      int zoom,
      int cachedZoom,
      GMapListener listener,
      boolean localFilesOnly) {

    int xIndex = x / GDataSource.sourceSize.width;
    int yIndex = y / GDataSource.sourceSize.height;

    xIndex += imgIndexX;
    yIndex += imgIndexY;

    BufferedImage image = null;
    if (!localFilesOnly || getGDataSource().isCached(xIndex, yIndex, zoom))
      image = getIndexedImage(xIndex, yIndex, zoom, cachedZoom, listener);

    int xCoord = x % GDataSource.sourceSize.width;
    int yCoord = y % GDataSource.sourceSize.height;

    // Checks for invalid xCoord and yCoord
    if (xCoord < 0) {
      xCoord = 0;
    }
    if (yCoord < 0) {
      yCoord = 0;
    }

    // get info about the image
    Dimension imageSize =
        new Dimension(getGDataSource().sourceSize.width, getGDataSource().sourceSize.height);

    // find the width of what we CAN paint
    int initPaintWidth = imageSize.width - xCoord;
    int initPaintHeight = imageSize.height - yCoord;

    int paintWidth = initPaintWidth;
    int paintHeight = initPaintHeight;

    int rowImages = numOfRows(x, y, h, zoom, cachedZoom);
    int colImages = numOfCols(x, y, w, zoom, cachedZoom);

    if (imgIndexX >= colImages || imgIndexY >= rowImages) {
      return null;
    }

    int xImage = 0;
    int yImage = 0;

    int xInitCoord = xCoord;
    int yInitCoord = yCoord;

    if (imgIndexX > 0) {
      xImage = initPaintWidth + (imgIndexX - 1) * imageSize.width;
      xCoord = 0;
      if (imgIndexX < (colImages - 1)) {
        paintWidth = imageSize.width;
      } else {
        paintWidth = w - ((colImages - 2) * imageSize.width) - (imageSize.width - xInitCoord);
      }
    }
    if (imgIndexY > 0) {
      yImage = initPaintHeight + (imgIndexY - 1) * imageSize.height;
      yCoord = 0;
      if (imgIndexY < (rowImages - 1)) {
        paintHeight = imageSize.height;
      } else {
        paintHeight = h - ((rowImages - 2) * imageSize.height) - (imageSize.height - yInitCoord);
      }
    }

    if (buffImg != null) {
      Graphics2D g = (Graphics2D) buffImg.getGraphics();
      if (image != null) {
        // System.out.println(xCoord + ":" + yCoord + ":" + paintWidth + ":" + paintHeight);
        g.drawImage(
            image.getSubimage(xCoord, yCoord, paintWidth, paintHeight),
            xImage,
            yImage,
            paintWidth,
            paintHeight,
            null);
      } else {
        Composite originalComposite = g.getComposite();
        g.setComposite(opacity40);
        g.setColor(Color.BLACK);
        g.fillRect(xImage, yImage, paintWidth, paintHeight);
        g.setComposite(originalComposite);
      }
    }

    return buffImg;
  }

  /** Calculates the number of rows of tiles needed to build current image. */
  public int numOfRows(int x, int y, int h, int zoom, int cachedZoom) {
    int xIndex = x / GDataSource.sourceSize.width;
    int yIndex = y / GDataSource.sourceSize.height;

    // BufferedImage image = getIndexedImage(xIndex,yIndex,zoom,cachedZoom);

    int yCoord = y % GDataSource.sourceSize.height;

    // find the width of what we CAN paint
    int paintHeight = GDataSource.sourceSize.height - yCoord;

    int rowImages;

    // Calculate number of row images
    if ((h - paintHeight) % 256 == 0) {
      rowImages = 1 + (h - paintHeight) / 256;
    } else {
      rowImages = 2 + (h - paintHeight) / 256;
    }

    return rowImages;
  }
  /** Calculates the number of columns of tiles needed to build current image. */
  public int numOfCols(int x, int y, int w, int zoom, int cachedZoom) {
    int xIndex = x / GDataSource.sourceSize.width;
    int yIndex = y / GDataSource.sourceSize.height;

    // BufferedImage image = getIndexedImage(xIndex,yIndex,zoom,cachedZoom);

    int xCoord = x % GDataSource.sourceSize.height;

    // find the width of what we CAN paint
    int paintWidth = GDataSource.sourceSize.width - xCoord;

    int colImages;

    // Calculate number of row images
    if ((w - paintWidth) % 256 == 0) {
      colImages = 1 + (w - paintWidth) / 256;
    } else {
      colImages = 2 + (w - paintWidth) / 256;
    }

    return colImages;
  }

  public BufferedImage getIndexedImage(int x, int y, int zoom, int cacheZoom) {
    return getIndexedImage(x, y, zoom, cacheZoom, null);
  }
  /** Get an image based on index numbers */
  public BufferedImage getIndexedImage(
      int x, int y, int zoom, int cacheZoom, GMapListener listener) {

    if (listener != null) {
      if (!getGDataSource().isCached(x, y, zoom)) {
        listener.updateGMapPainting();
        listener.updateGMapMessage(GMap.MESSAGE_DOWNLOADING);
      } else {
        listener.updateGMapMessage(GMap.MESSAGE_PAINTING);
      }
    }

    BufferedImage thumbImage = getGDataSource().getImage(x, y, zoom, true);

    if (thumbImage == null) return defaultImage;

    // if we dont have to paint cache, return here
    if (cacheZoom == (GPhysicalPoint.MIN_ZOOM - 1) || cacheZoom >= zoom) return thumbImage;

    BufferedImage paintedImage =
        new BufferedImage(
            GDataSource.sourceSize.width,
            GDataSource.sourceSize.height,
            BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics2D = paintedImage.createGraphics();
    graphics2D.drawImage(
        thumbImage, 0, 0, GDataSource.sourceSize.width, GDataSource.sourceSize.height, null);

    // now lets move to painting the cache
    double imageNum = Math.pow(2, zoom - cacheZoom);

    // draw cache lines
    int startX = (int) (imageNum * x);
    int startY = (int) (imageNum * y);

    // get composite to restore later, set new transparent composite
    Composite originalComposite = graphics2D.getComposite();
    graphics2D.setComposite(opacity40);

    // draw grid
    for (int i = 0; i < imageNum; i++) {
      for (int j = 0; j < imageNum; j++) {
        // points
        Point upperLeft =
            new Point(
                (int) (GDataSource.sourceSize.width / imageNum) * i,
                (int) (GDataSource.sourceSize.height / imageNum) * j);
        Dimension size =
            new Dimension(
                (int) (GDataSource.sourceSize.width / imageNum),
                (int) (GDataSource.sourceSize.height / imageNum));

        // draw lines
        graphics2D.setColor(new Color(100, 100, 100));
        graphics2D.drawLine(upperLeft.x, upperLeft.y, upperLeft.x + size.width, upperLeft.y);
        graphics2D.drawLine(upperLeft.x, upperLeft.y, upperLeft.x, upperLeft.y + size.height);

        // check if file exists
        if (getGDataSource().isCached(startX + i, startY + j, cacheZoom))
          graphics2D.setColor(Color.RED);
        else graphics2D.setColor(new Color(155, 155, 155));

        // shade rectangle
        graphics2D.fillRect(upperLeft.x, upperLeft.y, size.width, size.height);
      }
    }

    // restore composite
    graphics2D.setComposite(originalComposite);

    return paintedImage;
  }

  // initialize default image
  private BufferedImage getDefaultImage(int w, int h) {
    BufferedImage defaultImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics2D graphics2D = defaultImage.createGraphics();
    graphics2D.setColor(new Color(200, 200, 200));
    graphics2D.fillRect(0, 0, w, h);
    graphics2D.setColor(new Color(130, 130, 130));
    graphics2D.drawRect(0, 0, w - 1, h - 1);
    return defaultImage;
  }

  /** Method to set the <tt>cacheDirectory</tt> property. */
  public void setCacheDirectory() {}
}
    public void paintComponent(Graphics g) {
      super.paintComponent(g);

      Graphics2D g2 = (Graphics2D) g;

      AlphaComposite ac, ac2 = null;
      ac2 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
      for (int i = 0; i < imagenum_now.length; i++) {
        for (int j = 0; j < imagenum_now[i].length; j++) {
          // System.out.println("x: " + i + ", y: " + j);

          g2.setComposite(ac2);

          if (imagenum_now[i][j] != -1) {
            g2.drawImage(
                // images.get(imagenum_now[i][j])
                // getImage(images.get(imagenum_now[i][j])),
                imagenum_now2[i][j], i * size_x, j * size_y, size_x, size_y, this);
          } else {
            // No picture found, ignoring
            // System.out.println("imagenum_now["+i+"]["+j+"] = -1");
          }

          try {
            ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, fade[i][j]);
          } catch (IllegalArgumentException e) {
            ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f);
          }
          g2.setComposite(ac);
          if (imagenum_next[i][j] != -1) {
            g2.drawImage(
                // images.get(imagenum_next[i][j]),
                // getImage(images.get(imagenum_next[i][j])),
                imagenum_next2[i][j], i * size_x, j * size_y, size_x, size_y, this);
          } else {
            // No picture found, ignoring
            // System.out.println("imagenum_now["+i+"]["+j+"] = -1");
          }

          /*
          if(i == 0 && j == 0)
          	System.out.println("" + imagenum_now[i][j] +
          			" => " +
          			imagenum_next[i][j] + ", fade: "+fade[i][j]);;
          */

          // Red border if the image is new
          if (number_of_frames_redborder != -1
              && (images_nevershown.contains((Integer) imagenum_next[i][j])
                  || images_nevershown.contains((Integer) imagenum_now[i][j]))) {
            g2.setComposite(ac2);
            g2.setColor(color_redborder);
            int bordertime = redborder[i][j];
            if (bordertime > 0) {
              // Draw border
              g2.drawRect(i * size_x, j * size_y, size_x - 1, size_y - 1);

              if (bordertime > number_of_frames_redborder) {
                // No more border
                redborder[i][j] = -number_of_frames_redborder;
              }
            }
            redborder[i][j]++;
          }
        }
      }
    }
Example #16
0
  public void paint(Graphics g) // function that puts everything on the screen
      {
    Graphics2D scene = (Graphics2D) g; // Not really sure what this is. Blame Victor
    // use scene to draw the background

    scene.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g.clearRect(0, 0, SCREENWIDTH, SCREENHEIGHT); // Clears the screen

    Font q =
        new Font(
            "Source Sans Pro", Font.PLAIN, 40); // Makes the font we use for options and story text
    g.setFont(q); // Sets the default font

    g.setColor(Color.white);

    if (state == 1) // Story text
    {
      drawTag(g);
      g.drawImage(textBox, 0, 0, null); // draw the story boxes
      Font n = new Font("Source Sans Pro", Font.BOLD, 48); // Makes the font for the names
      g.setFont(n); // Sets the name font
      scene.drawString(nameC, 53, 435); // Draws the current name
      g.setFont(q); // sets the quote font

      fm = g.getFontMetrics();

      ArrayList<String> lines = new ArrayList<String>();
      String line = "";

      for (int i = 0; i < quoteC.length(); i++) {
        line += quoteC.charAt(i);
        if (fm.stringWidth(line) > 1180) {
          String lineCopy = line;
          line = line.substring(0, lineCopy.lastIndexOf(' '));
          i -= lineCopy.length() - lineCopy.lastIndexOf(' ') - 1;
          lines.add(line);
          line = "";
        }
      }
      lines.add(line);

      for (int i = 0; i < lines.size(); i++) {
        scene.drawString(lines.get(i), 40, 535 + 65 * i);
      }
    } else if (state == 2) // Draws the options
    {
      scene.drawImage(bg, screenShakeX, screenShakeY, null);
      scene.drawImage(obox, screenShakeX, screenShakeY, null); // options thing
      scene.drawString(options.get(0), 220, 255);
      scene.drawString(options.get(1), 220, 375);
      scene.drawString(options.get(2), 220, 495);
    } else if (state == 3) // Game is over
    {
      scene.drawImage(oldbg, screenShakeX, screenShakeY, null);

      float opacity = fadeCounter / FADETIMELIMIT;
      if (opacity > 1.0f) opacity = 1.0f;
      scene.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
      scene.drawImage(bg, screenShakeX, screenShakeY, null); // draws the background image
      scene.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
      scene.drawString("The end", 40, 520); // End screen
    }
  }
Example #17
0
/**
 * A ButtonUI that includes an enclosed filled shape.
 *
 * <p>This <code>ButtonUI</code> supports several options for controlling the shape of separate
 * buttons. (Note one instance of each UI can be assigned to several buttons, and each button can be
 * configured differently).
 *
 * <p>Each button can have a horizontal and vertical position, allowing grids of buttons to be
 * seamlessly connected. Horizontal positions can be LEFT, MIDDLE, RIGHT and ONLY, and vertical
 * positions can be TOP, MIDDLE, BOTTOM, and ONLY. You can set these positions by called:
 *
 * <p><code>myButton.putClientProperty(HORIZONTAL_POSITION, LEFT)</code>
 *
 * <p>Also you can define an arbitrary shape for each button. If this is defined, that shape takes
 * priority over all other curvature/segment information. You can define this by calling something
 * like:
 *
 * <p><code>myButton.putClientProperty(SHAPE, new Ellipse2D.Float(0,0,100,100));</code>
 *
 * <p>The size of the shape is not important: it will be scaled as necessary to fit the icon and
 * text of each button. It is essential that the center of this shape be inside the shape. (That is,
 * a 'C' or 'O' shape is not valid.)
 *
 * <p>This layout is not tested with HTML-rendered text.
 *
 * @see com.bric.plaf.FilledButtonUIDemo
 * @see <a href="http://javagraphics.blogspot.com/2009/08/buttons-new-uis.html">Buttons: New UIs</a>
 */
public abstract class FilledButtonUI extends ButtonUI implements PositionConstants {

  /**
   * Assign this client property to control whether the path stroke should be painted. The default
   * is assigned to be true.
   */
  public static final String STROKE_PAINTED = "stroke-painted";

  /**
   * Assign this client property to control whether the button should be rendered as enabled or not.
   *
   * <p>When this is null: the enabled state is taken directly from the button. But if the button is
   * disabled and this property is true: then the button is still rendered as if it were enabled
   * (and vice versa).
   */
  public static final String ENABLED_STATE = "enabled-rendering";

  /**
   * Basic information about the geometry/layout of buttons. The members are final, and should be
   * redefined instead of replaced.
   */
  static class ButtonInfo {

    /** This handles most -- but not all -- of the basic workings of a generic button. */
    final BasicButtonListener basicListener;

    /** The button this information relates to. */
    final AbstractButton button;

    /** A list of <code>PaintUIEffect</code>, in the order they should be rendered. */
    protected final Vector<PaintUIEffect> effects = new Vector<PaintUIEffect>();

    protected final Rectangle fillBounds = new Rectangle();

    /** The rectangle the icon is painted to. */
    protected final Rectangle iconRect = new Rectangle();

    /** The rectangle the text is painted to. */
    protected final Rectangle textRect = new Rectangle();

    /** The UI that relates to this ButtonInfo object. */
    final FilledButtonUI ui;

    /** Completely untested. */
    protected final Rectangle viewRect = new Rectangle();

    /** The area that makes up this button. */
    protected final GeneralPath fill = new GeneralPath();

    /**
     * The stroke/border of this button. This is the shape that is rendered with a <code>
     * java.awt.Stroke</code>. It is generally the same -- or very similar to -- the fill shape.
     */
    protected final GeneralPath stroke = new GeneralPath();

    public ButtonInfo(AbstractButton b, FilledButtonUI filledButtonUI) {
      button = b;
      ui = filledButtonUI;

      basicListener =
          new BasicButtonListener(button) {
            Timer focusBlinker;

            String BLINK_STATE_KEY = "FilledButtonUI.blinkState";

            @Override
            public void focusGained(FocusEvent e) {
              super.focusGained(e);
              if (focusBlinker == null) {
                int rate = UIManager.getInt("TextField.caretBlinkRate");
                if (rate < 100) rate = 500;

                focusBlinker =
                    new Timer(
                        rate,
                        new ActionListener() {
                          public void actionPerformed(ActionEvent e) {
                            Boolean blinkState =
                                (Boolean) button.getClientProperty(BLINK_STATE_KEY);
                            if (blinkState == null) blinkState = Boolean.TRUE;
                            button.putClientProperty(HAS_FOCUS, blinkState && button.hasFocus());
                            button.putClientProperty(BLINK_STATE_KEY, !blinkState);
                          }
                        });
              }
              button.putClientProperty(BLINK_STATE_KEY, null);
              Boolean blinkActive = (Boolean) button.getClientProperty("Focus.blink");
              if (blinkActive != null && blinkActive) focusBlinker.start();
            }

            @Override
            public void focusLost(FocusEvent e) {
              super.focusLost(e);
              button.putClientProperty(SPACEBAR_PRESSED, Boolean.FALSE);
              button.putClientProperty(HAS_FOCUS, null);
              if (focusBlinker != null) focusBlinker.stop();
              button.repaint();
            }

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
              super.propertyChange(evt);
              if (evt.getPropertyName()
                  .equals(AbstractButton.CONTENT_AREA_FILLED_CHANGED_PROPERTY)) {
                if (button.isOpaque()
                    && evt.getOldValue().equals(Boolean.FALSE)
                    && evt.getNewValue().equals(Boolean.TRUE)) {
                  // the BasicButtonListener may set the opacity to true
                  // we want to reverse that here:
                  button.setOpaque(false);
                }
              } else if (evt.getPropertyName().equals(SPACEBAR_PRESSED)) {
                button.repaint();
              } else if (evt.getPropertyName().equals(HAS_FOCUS)) {
                button.repaint();
              } else if (evt.getPropertyName().equals("text")
                  || evt.getPropertyName().equals("icon")) {
                ui.updateLayout(button, getButtonInfo(button));
                button.repaint();
              }
            }
          };
    }

    public void updateFillBounds() {
      ShapeBounds.getBounds(fill, fillBounds);
    }
  }

  private static Hashtable<Font, Integer> ascentTable = new Hashtable<Font, Integer>();

  /** A possible value for the VERTICAL_POSITION client property. */
  public static final String BOTTOM = "bottom";

  private static final String BUTTON_INFO_KEY = "com.bric.plaf.FilledButtonUI.ButtonInfo";

  /** When a component is resized, <code>updateLayout</code> is called. */
  protected static final ComponentListener componentListener =
      new ComponentListener() {

        public void componentHidden(ComponentEvent e) {}

        public void componentMoved(ComponentEvent e) {
          componentResized(e);
        }

        public void componentResized(ComponentEvent e) {
          AbstractButton button = (AbstractButton) e.getSource();
          ButtonInfo info = getButtonInfo(button);
          info.ui.updateLayout(button, info);
          button.repaint();
        }

        public void componentShown(ComponentEvent e) {
          componentResized(e);
        }
      };

  /**
   * If this client-property is non-null: then it overrides whether focus is actually present when
   * deciding to render the focus.
   */
  protected static final String HAS_FOCUS = "FilledButtonUI.focusPainted";

  /** A static KeyListener for using focus arrow keys. */
  protected static KeyListener focusArrowListener = new FocusArrowListener();

  /**
   * The client property for the horizontal position of this segment. The recognized values are
   * "left", "middle", "last" and "only". The default value is assumed to be "only".
   */
  public static final String HORIZONTAL_POSITION = "JButton.segmentHorizontalPosition";

  /** This client property defines an arbitrary shape for each button. */
  public static final String SHAPE = "JButton.shape";

  protected static KeyListener keyArmingListener =
      new KeyListener() {
        public void keyPressed(KeyEvent e) {
          int code = e.getKeyCode();
          if (code == KeyEvent.VK_SPACE) {
            AbstractButton button = (AbstractButton) e.getSource();
            Boolean wasPressed = (Boolean) button.getClientProperty(SPACEBAR_PRESSED);
            if (wasPressed == null || wasPressed.booleanValue() == false) {
              button.putClientProperty(SPACEBAR_PRESSED, Boolean.TRUE);
              button.doClick();
            }
          }
        }

        public void keyReleased(KeyEvent e) {
          int code = e.getKeyCode();
          if (code == KeyEvent.VK_SPACE) {
            AbstractButton button = (AbstractButton) e.getSource();
            button.putClientProperty(SPACEBAR_PRESSED, Boolean.FALSE);
          }
        }

        public void keyTyped(KeyEvent e) {}
      };
  /** A possible value for the HORIZONTAL_POSITION client property. */
  public static final String LEFT = "left";

  /** A possible value for the HORIZONTAL_POSITION or VERTICAL_POSITION client property. */
  public static final String MIDDLE = "middle";

  /** A possible value for the HORIZONTAL_POSITION or VERTICAL_POSITION client property. */
  public static final String ONLY = "only";

  /**
   * An optional client property that map to a {@link PaintFocus} constant to control how to paint
   * the focus of a button.
   */
  public static final String PAINT_FOCUS_BEHAVIOR_KEY = "FilledButtonUI.PaintFocusBehavior";

  /** Different behaviors to paint the keyboard focus. */
  public static enum PaintFocus {
    /** Focus should be painted along the edge of the filled shape -- both inside and outside. */
    BOTH,
    /** Focus should be painted just inside the filled shape. */
    INSIDE,

    /**
     * Focus should be painted just outside the filled shape. This is taken into account when
     * allocating the button size, because it adds extra pixels to the width/height.
     */
    OUTSIDE,

    /**
     * No focus is explicitly painted.
     *
     * <p>You may use this constant when you aren't happy with how the <code>paint()</code> method
     * handles focus by default, and paint your own focus by override <code>paintBackground()</code>
     * or <code>paintForeground()</code>.
     */
    NONE
  };

  /** When the position properties change in a button, we need to update the UI. */
  protected static PropertyChangeListener positionAndShapeListener =
      new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
          String name = evt.getPropertyName();
          if (name.equals(VERTICAL_POSITION)
              || name.equals(HORIZONTAL_POSITION)
              || name.equals(SHAPE)
              || name.equals("JButton.segmentPosition")) { // see Apple Tech Note 2196
            AbstractButton button = (AbstractButton) evt.getSource();
            ButtonUI ui = button.getUI();
            if (ui instanceof FilledButtonUI) {
              FilledButtonUI s = (FilledButtonUI) ui;
              s.updateLayout(button, getButtonInfo(button));
              button.invalidate();
              button.repaint();
            }
          }
        }
      };

  /** A possible value for the HORIZONTAL_POSITION client property. */
  public static final String RIGHT = "right";

  /**
   * This client property is set to a Boolean indicating whether the spacebar is currently pressed
   * or not.
   */
  protected static final String SPACEBAR_PRESSED = "FilledButtonUI.spacebarPressed";

  /**
   * This client property is set to a Boolean indicating whether to render a button as if the mouse
   * is rolled over it or not.
   */
  protected static final String ROLLOVER = "FilledButtonUI.rollover";

  /** A translucent composite used to render parts the UI when a button is disabled. */
  protected static AlphaComposite SRC_OVER_TRANSLUCENT =
      AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f);

  /** A possible value for the VERTICAL_POSITION client property. */
  public static final String TOP = "top";

  /**
   * The client property for the vertical position of this segment. The recognized values are "top",
   * "middle", "bottom" and "only". The default value is assumed to be "only".
   */
  public static final String VERTICAL_POSITION = "JButton.segmentVerticalPosition";

  protected static ButtonInfo getButtonInfo(AbstractButton button) {
    ButtonInfo i = (ButtonInfo) button.getClientProperty(BUTTON_INFO_KEY);
    if (i == null) throw new NullPointerException("installUI was not called");
    return i;
  }

  /**
   * The client property that maps to a Boolean indicating whether segmented buttons should show a
   * partition or not. The default value is assumed to be true.
   */
  public static final String SHOW_SEPARATORS = "FilledButtonUI.showSeparators";

  protected boolean isShowingSeparators(AbstractButton button) {
    Boolean showSeparators = (Boolean) button.getClientProperty(SHOW_SEPARATORS);
    if (showSeparators == null) return true;
    return showSeparators;
  }

  protected void updateLayout(AbstractButton button, ButtonInfo buttonInfo) {
    Shape customShape = (Shape) button.getClientProperty(SHAPE);
    int width = button.getWidth();
    int height = button.getHeight();
    int horizontalPosition = getHorizontalPosition(button);
    int verticalPosition = getVerticalPosition(button);

    String key = width + " " + height + " " + horizontalPosition + " " + verticalPosition;
    button.putClientProperty("FilledButtonUI.validationKey", key);

    int dx = 0;
    int dy = 0;

    if (getFocusPainting(button) == PaintFocus.OUTSIDE
        || getFocusPainting(button) == PaintFocus.BOTH) {
      if (horizontalPosition == POS_LEFT || horizontalPosition == POS_ONLY) {
        dx += focusSize;
        width -= focusSize;
      }
      if (horizontalPosition == POS_RIGHT || horizontalPosition == POS_ONLY) {
        width -= focusSize;
      }
      if (verticalPosition == POS_TOP || verticalPosition == POS_ONLY) {
        dy += focusSize;
        height -= focusSize;
      }
      if (verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY) {
        height -= focusSize;
      }
    } else {
      if ((verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY)
          && fill.getShadowHighlight(button) != null) {
        height--;
      }
    }

    ButtonInfo info = getButtonInfo(button);
    boolean showSeparators = isShowingSeparators(button);

    shape.getShape(
        info.fill,
        info.stroke,
        width,
        height,
        horizontalPosition,
        verticalPosition,
        showSeparators,
        customShape);

    AffineTransform translation = AffineTransform.getTranslateInstance(dx, dy);
    info.fill.transform(translation);
    info.stroke.transform(translation);

    Font font = button.getFont();
    if (font == null) font = new Font("Default", 0, 12);
    FontMetrics fm = button.getFontMetrics(font);

    info.viewRect.x =
        info.viewRect.y =
            info.textRect.x = info.textRect.y = info.textRect.width = info.textRect.height = 0;
    info.iconRect.x = info.iconRect.y = info.iconRect.width = info.iconRect.height = 0;
    info.viewRect.width = Short.MAX_VALUE;
    info.viewRect.height = Short.MAX_VALUE;

    SwingUtilities.layoutCompoundLabel(
        fm,
        button.getText(),
        button.getIcon(),
        button.getVerticalAlignment(),
        button.getHorizontalAlignment(),
        button.getVerticalTextPosition(),
        button.getHorizontalTextPosition(),
        info.viewRect,
        info.iconRect,
        info.textRect,
        button.getIconTextGap());

    Insets textInsets = getTextPadding();
    Insets iconInsets = getIconPadding();

    Rectangle tempTextRect = new Rectangle(info.textRect);
    Rectangle tempIconRect = new Rectangle(info.iconRect);
    if (info.textRect.width > 0) {
      tempTextRect.y -= textInsets.top;
      tempTextRect.x -= textInsets.left;
      tempTextRect.width += textInsets.left + textInsets.right;
      tempTextRect.height += textInsets.top + textInsets.bottom;
    }
    if (info.iconRect.width > 0) {
      tempIconRect.y -= iconInsets.top;
      tempIconRect.x -= iconInsets.left;
      tempIconRect.width += iconInsets.left + iconInsets.right;
      tempIconRect.height += iconInsets.top + iconInsets.bottom;
    }

    Rectangle sum = getSum(new Rectangle[] {tempIconRect, tempTextRect});

    Insets padding = getContentInsets(button);

    float centerX, centerY;
    if (button.getHorizontalAlignment() == SwingConstants.LEFT
        || button.getHorizontalAlignment() == SwingConstants.LEADING) {
      centerX = padding.left + sum.width / 2;
    } else if (button.getHorizontalAlignment() == SwingConstants.RIGHT
        || button.getHorizontalAlignment() == SwingConstants.TRAILING) {
      centerX = button.getWidth() - padding.right - sum.width / 2;
    } else {
      centerX = ((button.getWidth() - padding.left - padding.right)) / 2f;
    }
    // TODO: also take into account vertical alignment:
    centerY = ((button.getHeight() - padding.top - padding.bottom)) / 2f;

    float shiftX = centerX - (sum.width) / 2f - sum.x + padding.left;
    float shiftY = centerY - (sum.height) / 2f - sum.y + padding.top;

    if (customShape == null) {
      if (button.getVerticalAlignment() == SwingConstants.CENTER
          && button.getVerticalTextPosition() == SwingConstants.CENTER
          && info.textRect.width > 0) {
        int unusedAscent = getUnusedAscent(fm, font);
        int ascent = fm.getAscent() - unusedAscent;

        shiftY =
            (int) (-sum.y + centerY - ascent / 2 - unusedAscent + padding.top - textInsets.top);
      }
    }

    info.iconRect.setFrame(
        info.iconRect.x + shiftX,
        info.iconRect.y + shiftY,
        info.iconRect.width,
        info.iconRect.height);
    info.textRect.setRect(
        (int) (info.textRect.x + shiftX + .5f),
        (int) (info.textRect.y + shiftY + .5f),
        info.textRect.width,
        info.textRect.height);

    info.updateFillBounds();
  }

  /**
   * This looks at the client properties "JButton.segmentPosition" and HORIZONTAL_POSITION to return
   * on the constants in this class (LEFT_POS, POS_MIDDLE, RIGHT_POS or POS_ONLY).
   *
   * <p>This returns POS_ONLY if a shape is defined, because in this context a position doesn't make
   * sense.
   */
  protected static int getHorizontalPosition(JComponent b) {
    if (b == null) return POS_ONLY;

    Shape shape = (Shape) b.getClientProperty(SHAPE);
    if (shape != null) {
      return POS_ONLY;
    }

    String s = (String) b.getClientProperty("JButton.segmentPosition");
    if (s == null) s = (String) b.getClientProperty(HORIZONTAL_POSITION);
    if (s == null) s = "only";
    if (s.equalsIgnoreCase("first") || s.equalsIgnoreCase("left")) return POS_LEFT;
    if (s.equalsIgnoreCase("middle")) return POS_MIDDLE;
    if (s.equalsIgnoreCase("last") || s.equalsIgnoreCase("right")) return POS_RIGHT;
    return POS_ONLY;
  }

  /** 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;
  }

  /**
   * This deals with a bug/peculiarity for the default Mac font: several pixels of the ascent are
   * actually empty. This screws up certain measurements which assume the font is actually a few
   * pixels taller than it really is.
   */
  private static int getUnusedAscent(FontMetrics fm, Font font) {
    Integer value = ascentTable.get(font);
    if (value == null) {
      int recordedAscent = fm.getAscent();
      FontRenderContext frc = new FontRenderContext(new AffineTransform(), false, false);
      GlyphVector gv = font.createGlyphVector(frc, "XYZ");
      Rectangle2D bounds = ShapeBounds.getBounds(gv.getOutline());
      int observedAscent = (int) (Math.ceil(bounds.getHeight()) + .5);
      value = new Integer(recordedAscent - observedAscent);
      ascentTable.put(font, value);
    }
    return value.intValue();
  }
  /**
   * This looks at the client property VERTICAL_POSITION to return on the constants in this class
   * (POS_TOP, POS_MIDDLE, POS_BOTTOM or POS_ONLY).
   *
   * <p>This returns POS_ONLY if a shape is defined, because in this context a position doesn't make
   * sense.
   */
  protected static int getVerticalPosition(JComponent b) {
    if (b == null) return POS_ONLY;

    Shape shape = (Shape) b.getClientProperty(SHAPE);
    if (shape != null) {
      return POS_ONLY;
    }

    String s = (String) b.getClientProperty(VERTICAL_POSITION);
    if (s == null) s = "only";
    if (s.equalsIgnoreCase("top")) return POS_TOP;
    if (s.equalsIgnoreCase("middle")) return POS_MIDDLE;
    if (s.equalsIgnoreCase("bottom")) return POS_BOTTOM;
    return POS_ONLY;
  }

  /**
   * Return true if the spacebar is pressed. This consults the SPACEBAR_PRESSED property, which is
   * correctly controlled if a FilledButtonUI is installed in a given button.
   *
   * <p>This is visually the same as setting the ButtonModel's pressed state to true. However if
   * that property were used and the mouse was interacting with this button: the two agents (the
   * KeyListener and the MouseListener) would constantly be overriding the other's work.
   */
  protected static boolean isSpacebarPressed(AbstractButton button) {
    Boolean b = (Boolean) button.getClientProperty(SPACEBAR_PRESSED);
    if (b == null) return false;
    return b.booleanValue();
  }

  /**
   * Return true if this button should render as if the mouse is over it. This first checks the
   * ROLLOVER client property to determine if an artificial state is being induced; if that is
   * undefined then the ButtonModel's isRollover() method is used.
   */
  protected static boolean isRollover(AbstractButton button) {
    Boolean b = (Boolean) button.getClientProperty(ROLLOVER);
    if (b == null) return button.getModel().isRollover();
    return b;
  }

  /** The <code>ButtonFill</code> that controls the main paints used in this L&amp;F. */
  protected final ButtonFill fill;

  /** The number of pixels thick the focus ring should be. */
  protected int focusSize = 3;

  /** The ButtonShape responsible for the shape of this button. */
  protected final ButtonShape shape;

  /**
   * Creates a new <code>FilledButtonUI</code>.
   *
   * @param buttonFill the <code>ButtonFill</code> this UI uses.
   * @param buttonShape the <code>ButtonShape</code> this UI uses.
   */
  public FilledButtonUI(ButtonFill buttonFill, ButtonShape buttonShape) {
    shape = buttonShape;
    fill = buttonFill;
  }

  /**
   * The padding between the "content area" (that is, the icon rect and text rect) and the edges of
   * this button. This is a calculated value.
   */
  protected Insets getContentInsets(AbstractButton button) {
    int horizontalPosition = getHorizontalPosition(button);
    int verticalPosition = getVerticalPosition(button);

    Insets i = new Insets(0, 0, 0, 0);
    if (getFocusPainting(button) == PaintFocus.OUTSIDE
        || getFocusPainting(button) == PaintFocus.BOTH) {
      if (horizontalPosition == POS_LEFT || horizontalPosition == POS_ONLY) {
        i.left += focusSize;
      }
      if (horizontalPosition == POS_RIGHT || horizontalPosition == POS_ONLY) {
        i.right += focusSize;
      }
      if (verticalPosition == POS_TOP || verticalPosition == POS_ONLY) {
        i.top += focusSize;
      }
      if (verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY) {
        i.bottom += focusSize;
      }
    } else {
      if (fill.getShadowHighlight(button) != null
          && (verticalPosition == POS_BOTTOM || verticalPosition == POS_ONLY)) {
        i.bottom++;
      }
    }
    return i;
  }

  /** Returns the list of <code>PaintUIEffect</code> this button is rendering. */
  public List<PaintUIEffect> getEffects(AbstractButton button) {
    ButtonInfo info = getButtonInfo(button);
    return info.effects;
  }

  /**
   * Returns one of the PAINT_FOCUS constants declared in this object. If PAINT_NO_FOCUS is used,
   * then this class automatically paints no focus. In that case a subclass would be responsible for
   * any rendering of focus.
   *
   * <p>If PAINT_FOCUS_OUTSIDE is used, then a few rings of focus are painted outside this component
   * under this component. The order of painting is: <br>
   * 1. Shadow Highlight <br>
   * 2. Focus <br>
   * 3. Background Fill <br>
   * 4. Stroke
   *
   * <p>If PAINT_FOCUS_INSIDE is used, then a few rings of focus are painted inside this component.
   * The order of painting is: <br>
   * 1. Shadow Highlight <br>
   * 2. Background Fill <br>
   * 3. Focus <br>
   * 4. Stroke
   *
   * <p>If PAINT_FOCUS_BOTH is used, then the focus appears both inside and outside the filled area.
   * The order of painting is: <br>
   * 1. Shadow Highlight <br>
   * 2. Background Fill <br>
   * 3. Stroke <br>
   * 4. Focus
   *
   * <p>By default this returns PAINT_FOCUS_OUTSIDE if a shape is defined, or if this button is in a
   * single row or column of buttons. (That is, if the horizontal or vertical position is "only").
   * Otherwise this returns PAINT_FOCUS_INSIDE, because once you get to inner buttons the focus
   * <i>has</i> to be painted on the inside to remain visible.
   */
  public PaintFocus getFocusPainting(AbstractButton button) {
    PaintFocus f = (PaintFocus) button.getClientProperty(PAINT_FOCUS_BEHAVIOR_KEY);
    if (f != null) return f;

    Shape shape = (Shape) button.getClientProperty(SHAPE);
    if (shape != null) return PaintFocus.OUTSIDE;

    int horizontalPosition = getHorizontalPosition(button);
    int verticalPosition = getVerticalPosition(button);

    if (!(horizontalPosition == POS_ONLY || verticalPosition == POS_ONLY)) {
      return PaintFocus.INSIDE;
    }
    return PaintFocus.OUTSIDE;
  }

  /** Return a copy of the rectangle used to render the icon. */
  public Rectangle getIconBounds(AbstractButton button) {
    return new Rectangle(getButtonInfo(button).iconRect);
  }

  /**
   * This padding is added to the icon rectangle when the content area is being calculated. That is:
   * this is the minimum number of pixels that should be between the icon and the edge of this
   * button.
   *
   * <p>This is a constant value that other calculations use.
   */
  protected Insets getIconPadding() {
    return new Insets(2, 3, 2, 3);
  }

  /** This returns the preferred size. */
  @Override
  public Dimension getMaximumSize(JComponent jc) {
    // if this method returns
    // return new Dimension(Integer.MAX_VALUE/2, Integer.MAX_VALUE/2);
    return getPreferredSize(jc);
  }

  /** Returns the preferred size. */
  @Override
  public Dimension getMinimumSize(JComponent jc) {
    return getPreferredSize(jc);
  }

  /**
   * This is the minimum height of the content area of this button. That is: if this button has a
   * solid gray fill: this is the height of those gray pixels.
   *
   * <p>This height will only be used if it is <i>less than</i> the preferred height the text and
   * icon would otherwise require.
   *
   * <p>Also this will not be used for buttons with a custom shape.
   */
  protected int getPreferredHeight() {
    return 0;
  }

  /** Calculates the preferred size of this button and UI. */
  @Override
  public Dimension getPreferredSize(JComponent c) {
    AbstractButton button = (AbstractButton) c;
    ButtonCluster cluster = ButtonCluster.getCluster(button);

    Rectangle scratchIconRect = new Rectangle();
    Rectangle scratchTextRect = new Rectangle();
    Rectangle scratchViewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);

    FontMetrics fm = button.getFontMetrics(button.getFont());
    SwingUtilities.layoutCompoundLabel(
        fm,
        button.getText(),
        button.getIcon(),
        button.getVerticalAlignment(),
        button.getHorizontalAlignment(),
        button.getVerticalTextPosition(),
        button.getHorizontalTextPosition(),
        scratchViewRect,
        scratchIconRect,
        scratchTextRect,
        button.getIconTextGap());

    Insets textInsets = getTextPadding();
    scratchTextRect.y -= textInsets.top;
    scratchTextRect.x -= textInsets.left;
    scratchTextRect.width += textInsets.left + textInsets.right;
    scratchTextRect.height += textInsets.top + textInsets.bottom;

    Insets iconInsets = getIconPadding();
    scratchIconRect.y -= iconInsets.top;
    scratchIconRect.x -= iconInsets.left;
    scratchIconRect.width += iconInsets.left + iconInsets.right;
    scratchIconRect.height += iconInsets.top + iconInsets.bottom;

    Rectangle sum = getSum(new Rectangle[] {scratchIconRect, scratchTextRect});

    if (cluster != null && cluster.isStandardized()) {
      /**
       * If standardize: the dimensions of this button need to make room for all other buttons in
       * the cluster.
       */
      AbstractButton[] buttons = cluster.getButtons();
      for (int a = 0; a < buttons.length; a++) {
        ButtonUI ui = buttons[a].getUI();
        if (ui instanceof FilledButtonUI) {
          FilledButtonUI fui = (FilledButtonUI) ui;
          Dimension contentSize = fui.getContentSize(buttons[a]);
          sum.width = Math.max(sum.width, contentSize.width);
          sum.height = Math.max(sum.height, contentSize.height);
        }
      }
    }

    Insets padding = getContentInsets(button);

    Shape customShape = (Shape) button.getClientProperty(SHAPE);

    if (customShape == null) {
      int minHeight = getPreferredHeight();
      if (sum.height < minHeight) sum.height = minHeight;
    }

    int horizontalPosition = getHorizontalPosition(button);
    int verticalPosition = getVerticalPosition(button);
    Dimension size = shape.getPreferredSize(null, sum.width, sum.height, padding, customShape);

    if (customShape == null) {
      PaintFocus focus = getFocusPainting(button);
      if (focus == PaintFocus.OUTSIDE || focus == PaintFocus.BOTH) {
        if (horizontalPosition == POS_ONLY) {
          size.width += 2 * focusSize;
        } else if (horizontalPosition != POS_MIDDLE) {
          size.width += focusSize;
        }
        if (verticalPosition == POS_ONLY) {
          size.height += 2 * focusSize;
        } else if (horizontalPosition != POS_MIDDLE) {
          size.height += focusSize;
        }
      }
    }

    return size;
  }

  /** Returns the dimensions required to display the icon and label. */
  private Dimension getContentSize(AbstractButton button) {
    Rectangle scratchIconRect = new Rectangle();
    Rectangle scratchTextRect = new Rectangle();
    Rectangle scratchViewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);

    FontMetrics fm = button.getFontMetrics(button.getFont());
    SwingUtilities.layoutCompoundLabel(
        fm,
        button.getText(),
        button.getIcon(),
        button.getVerticalAlignment(),
        button.getHorizontalAlignment(),
        button.getVerticalTextPosition(),
        button.getHorizontalTextPosition(),
        scratchViewRect,
        scratchIconRect,
        scratchTextRect,
        button.getIconTextGap());

    Insets textInsets = getTextPadding();
    scratchTextRect.y -= textInsets.top;
    scratchTextRect.x -= textInsets.left;
    scratchTextRect.width += textInsets.left + textInsets.right;
    scratchTextRect.height += textInsets.top + textInsets.bottom;

    Insets iconInsets = getIconPadding();
    scratchIconRect.y -= iconInsets.top;
    scratchIconRect.x -= iconInsets.left;
    scratchIconRect.width += iconInsets.left + iconInsets.right;
    scratchIconRect.height += iconInsets.top + iconInsets.bottom;

    Rectangle sum = getSum(new Rectangle[] {scratchIconRect, scratchTextRect});
    return new Dimension(sum.width, sum.height);
  }

  /** This returns the filled shape used to draw this button. */
  public GeneralPath getShape(AbstractButton button) {
    ButtonInfo info = getButtonInfo(button);
    return new GeneralPath(info.fill);
  }

  /** Return a copy of the rectangle used to render the text. */
  public Rectangle getTextBounds(AbstractButton button) {
    return new Rectangle(getButtonInfo(button).textRect);
  }

  /**
   * This padding is added to the text rectangle when the content area is being calculated. That is:
   * this is the minimum number of pixels that should be between the text and the edge of this
   * button.
   *
   * <p>This is a constant value that other calculations use.
   */
  protected Insets getTextPadding() {
    return new Insets(2, 4, 2, 4);
  }

  @Override
  public void installUI(JComponent c) {
    AbstractButton button = (AbstractButton) c;

    ButtonInfo info = new ButtonInfo(button, this);
    button.putClientProperty(BUTTON_INFO_KEY, info);

    button.addMouseListener(info.basicListener);
    button.addMouseMotionListener(info.basicListener);
    button.addFocusListener(info.basicListener);
    button.addPropertyChangeListener(info.basicListener);
    button.addChangeListener(info.basicListener);
    button.addKeyListener(focusArrowListener);
    button.addComponentListener(componentListener);
    button.addKeyListener(keyArmingListener);
    button.setRequestFocusEnabled(false);
    button.setFocusable(true);
    button.addPropertyChangeListener(positionAndShapeListener);
    button.setOpaque(false);
    button.setRolloverEnabled(true);

    if (button.getIcon() != null) {
      Font font = UIManager.getFont("IconButton.font");
      if (font != null) button.setFont(font); // miniature-ish
    }

    super.installUI(c);

    updateLayout(button, info);

    if (button.getFont() == null) {
      Font font = UIManager.getFont("Button.font");
      if (font == null) {
        font = new Font("Default", 0, 13);
      }
      button.setFont(font);
    }
  }

  /**
   * Controls whether the stroke is painted with antialiased rendering hints.
   *
   * <p>Returns <code>true</code>.
   */
  public boolean isStrokeAntialiased() {
    return true;
  }

  /**
   * This checks to see if updateLayout() needs to be called. Generally this returns true if the
   * width, height, or segment position has changed.
   */
  protected boolean isLayoutValid(AbstractButton button) {
    int horizontalPosition = getHorizontalPosition(button);
    int verticalPosition = getVerticalPosition(button);
    int width = button.getWidth();
    int height = button.getHeight();

    String key = width + " " + height + " " + horizontalPosition + " " + verticalPosition;

    String oldKey = (String) button.getClientProperty("FilledButtonUI.validationKey");
    if (oldKey == null) return false;

    if (oldKey.equals(key)) return true;

    return false;
  }

  protected boolean isEnabled(AbstractButton button) {
    Boolean b = (Boolean) button.getClientProperty(ENABLED_STATE);
    if (b != null) return b;
    return button.isEnabled();
  }

  protected Composite getComposite(AbstractButton button) {
    if (isEnabled(button) == false) {
      return SRC_OVER_TRANSLUCENT;
    }
    return AlphaComposite.SrcOver;
  }

  /**
   * Return true if this button should render as if it has the keyboard focus. This first checks the
   * HAS_FOCUS client property to determine if an artificial state is being induced; if that is
   * undefined then the button's hasFocus() method is consulted.
   */
  protected static boolean hasFocus(AbstractButton button) {
    Boolean hasFocus = (Boolean) button.getClientProperty(HAS_FOCUS);
    if (hasFocus == null) hasFocus = button.hasFocus();
    return hasFocus;
  }

  protected static boolean isStrokePainted(AbstractButton b) {
    Boolean t = (Boolean) b.getClientProperty(STROKE_PAINTED);
    if (t != null) return t;
    return b.isBorderPainted();
  }

  /**
   * This calls the other relevant <code>paint...()</code> methods in this object. The layering of
   * the focus varies based on whether it should be painted outside or inside the filled shape, but
   * otherwise the layers are:
   *
   * <ul>
   *   <li>Filling the bounds with <code>button.getBackground()</code> (if <code>button.isOpaque()
   *       </code> is true).
   *   <li>If <code>getShadowHighlight()</code> is non-null, painting the stroke/border 1 pixel
   *       below its usual location.
   *   <li><code>paintBackground(g)</code>
   *   <li><code>paintEffects(g,false)</code>
   *   <li><code>paintIcon(g)</code>
   *   <li><code>paintText(g)</code>
   *   <LI><code>paintForeground(g)</code>
   *   <LI><code>paintEffects(g,true)</code>
   * </ul>
   */
  @Override
  public void paint(Graphics g0, JComponent c) {
    AbstractButton button = (AbstractButton) c;

    if (isLayoutValid(button) == false) updateLayout(button, getButtonInfo(button));

    if (button.isOpaque()) {
      g0.setColor(button.getBackground());
      g0.fillRect(0, 0, button.getWidth(), button.getHeight());
    }

    Graphics2D g = new OptimizedGraphics2D((Graphics2D) g0);

    g.setComposite(getComposite(button));

    ButtonInfo info = getButtonInfo(button);

    Color highlight = fill.getShadowHighlight(button);
    if (highlight != null && isStrokePainted(button)) {
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g.translate(0, 1);
      g.setColor(highlight);
      g.draw(info.fill);
      g.translate(0, -1);
    }

    PaintFocus focus = getFocusPainting(button);
    boolean hasFocus = hasFocus(button);
    if (Boolean.FALSE.equals(hasFocus) || button.isFocusPainted() == false) focus = PaintFocus.NONE;

    // this shouldn't be an issue, but just in case:
    if (isEnabled(button) == false) focus = PaintFocus.NONE;

    if (focus == PaintFocus.OUTSIDE) {
      if (isFillOpaque()) {
        // the opaque fill will overwrite the inner part of
        // this stroke...
        PlafPaintUtils.paintFocus(g, info.stroke, focusSize);
      } else {
        // this still has some rendering quirks in
        // Quartz (remove the clipping to study closely)
        // ... but other than the top horizontal & vertical
        // line it's OK.  And even those are ... partly there.
        Graphics2D focusG = (Graphics2D) g.create();
        GeneralPath outsideClip = new GeneralPath(Path2D.WIND_EVEN_ODD);
        outsideClip.append(new Rectangle(0, 0, button.getWidth(), button.getHeight()), false);
        outsideClip.append(info.fill, false);
        focusG.clip(outsideClip);
        PlafPaintUtils.paintFocus(focusG, info.stroke, focusSize);
        focusG.dispose();
      }
    }
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

    paintBackground(g, info);
    paintEffects(g, info, true);

    g.setStroke(new BasicStroke(1));
    if (focus == PaintFocus.INSIDE) {
      Graphics2D focusG = (Graphics2D) g.create();
      focusG.clip(info.fill);
      PlafPaintUtils.paintFocus(focusG, info.stroke, focusSize);
      focusG.dispose();
      paintStroke(g, info);
    } else if (focus == PaintFocus.BOTH) {
      paintStroke(g, info);
      PlafPaintUtils.paintFocus(g, info.stroke, focusSize);
    } else {
      paintStroke(g, info);
    }

    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    paintIcon(g, info);
    paintText(g, info);

    g.setComposite(isEnabled(button) ? AlphaComposite.SrcOver : SRC_OVER_TRANSLUCENT);
    paintForeground(g, info);
    paintEffects(g, info, false);
  }

  public void paintBackground(Graphics2D g, ButtonInfo info) {
    if (info.button.isContentAreaFilled()) {
      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      Paint fillPaint = fill.getFill(info.button, info.fillBounds);
      g.setPaint(fillPaint);
      g.fill(info.fill);
    }
  }

  public void paintStroke(Graphics2D g, ButtonInfo info) {
    if (isStrokePainted(info.button)) {
      Paint strokeColor = fill.getStroke(info.button, info.fillBounds);
      g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
      if (isStrokeAntialiased()) {
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      } else {
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
      }
      g.setPaint(strokeColor);
      g.draw(info.stroke);
    }
  }

  /**
   * Paints effects for this button. The effects, if any, are listed in the <code>effects</code>
   * field of this object.
   *
   * @param g the Graphics2D to paint to.
   * @param background if true, then only the effects for the background are painted. If false, then
   *     only the effects for the foreground are painted.
   */
  protected void paintEffects(Graphics2D g, ButtonInfo info, boolean background) {
    int ctr = 0;
    while (ctr < info.effects.size()) {
      PaintUIEffect effect = info.effects.get(ctr);
      effect.paint((Graphics2D) g.create());
      if (effect.getState() == State.FINISHED) {
        info.effects.remove(ctr);
      } else {
        ctr++;
      }
    }
  }

  public void paintForeground(Graphics2D g, ButtonInfo info) {}

  public void paintIcon(Graphics2D g, ButtonInfo info) {
    AbstractButton button = info.button;
    Icon icon = button.getIcon();
    ButtonModel model = button.getModel();

    if (model.isRollover() && button.getRolloverIcon() != null) icon = button.getRolloverIcon();
    if (model.isPressed() && button.getPressedIcon() != null) icon = button.getPressedIcon();
    if (model.isSelected() && button.getSelectedIcon() != null) icon = button.getSelectedIcon();
    if (model.isRollover() && model.isSelected() && button.getRolloverSelectedIcon() != null)
      icon = button.getRolloverSelectedIcon();
    if (isEnabled(button) == false && button.getDisabledIcon() != null)
      icon = button.getDisabledIcon();
    if (isEnabled(button) == false && model.isSelected() && button.getDisabledIcon() != null)
      icon = button.getDisabledSelectedIcon();

    if (icon != null) {
      g.setComposite(isEnabled(button) ? AlphaComposite.SrcOver : SRC_OVER_TRANSLUCENT);
      icon.paintIcon(button, g, info.iconRect.x, info.iconRect.y);
    }
  }

  public void paintText(Graphics2D g, ButtonInfo info) {
    ButtonModel model = info.button.getModel();
    FontMetrics fm = info.button.getFontMetrics(info.button.getFont());
    int mnemonicIndex = info.button.getDisplayedMnemonicIndex();
    String text = info.button.getText();
    int textShiftOffset = 0;

    g.setComposite(AlphaComposite.SrcOver);
    /* Draw the Text */
    if (isEnabled(info.button)) {
      /** * paint the text normally */
      g.setColor(info.button.getForeground());
      BasicGraphicsUtils.drawStringUnderlineCharAt(
          g,
          text,
          mnemonicIndex,
          info.textRect.x + textShiftOffset,
          info.textRect.y + fm.getAscent() + textShiftOffset);
    } else {
      /** * paint the text disabled ** */
      g.setColor(info.button.getBackground().brighter());
      BasicGraphicsUtils.drawStringUnderlineCharAt(
          g, text, mnemonicIndex, info.textRect.x, info.textRect.y + fm.getAscent());
      g.setColor(info.button.getBackground().darker());
      BasicGraphicsUtils.drawStringUnderlineCharAt(
          g, text, mnemonicIndex, info.textRect.x - 1, info.textRect.y + fm.getAscent() - 1);
    }
  }

  @Override
  public void uninstallUI(JComponent c) {
    AbstractButton button = (AbstractButton) c;

    ButtonInfo info = getButtonInfo(button);

    button.removeMouseListener(info.basicListener);
    button.removeMouseMotionListener(info.basicListener);
    button.removeFocusListener(info.basicListener);
    button.removePropertyChangeListener(info.basicListener);
    button.removeChangeListener(info.basicListener);
    button.removeKeyListener(focusArrowListener);
    button.removeComponentListener(componentListener);
    button.removeKeyListener(keyArmingListener);
    button.removePropertyChangeListener(positionAndShapeListener);

    super.uninstallUI(c);
  }

  /** Return the {@link com.bric.plaf.ButtonFill} used by this FilledButtonUI. */
  public ButtonFill getButtonFill() {
    return fill;
  }

  /** Return the {@link com.bric.plaf.ButtonShape} used by this FilledButtonUI. */
  public ButtonShape getButtonShape() {
    return shape;
  }

  /**
   * This may be used to take some shortcuts in rendering the button if it is assumed that -- when
   * enabled and isContentArea is true -- the filled area of this button is opaque.
   */
  public abstract boolean isFillOpaque();

  @Override
  public boolean contains(JComponent c, int x, int y) {
    AbstractButton button = (AbstractButton) c;
    ButtonInfo info = getButtonInfo(button);
    if (isLayoutValid(button) == false) updateLayout(button, info);
    return info.fill.contains(x, y);
  }

  /**
   * Create a {@link com.bric.plaf.FilledComboBoxUI} modeled after this <code>FilledButtonUI</code>.
   */
  public FilledComboBoxUI createComboBoxUI() {
    return new FilledComboBoxUI(this);
  }
}
Example #18
0
  public void drawTag(Graphics g) {
    try {
      String b =
          tag.substring(
              tag.indexOf("B"), tag.indexOf("B") + 2); // gets the file name of the background file
      URL url = getClass().getResource(b + ".png");
      bg = ImageIO.read(url); // reads in the background file

      if (oldbg == null) {
        oldbg = bg;
        g.drawImage(bg, screenShakeX, screenShakeY, null);
      } else if (oldbg != bg) {
        if (fadeCounter == FADETIMELIMIT) {
          oldbg = bg;
          g.drawImage(bg, screenShakeX, screenShakeY, null); // draws the background image
        } else {
          g.drawImage(oldbg, screenShakeX, screenShakeY, null); // draws the background image

          float opacity = fadeCounter / FADETIMELIMIT;
          if (opacity > 1.0f) opacity = 1.0f;
          ((Graphics2D) g)
              .setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, opacity));
          ((Graphics2D) g)
              .drawImage(bg, screenShakeX, screenShakeY, null); // draws the background image
          ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
        }
      } else g.drawImage(bg, screenShakeX, screenShakeY, null); // draws the background image

      if (tag.contains("H")) screenShakeUpdate = true;

      if (tag.contains("T")) // Two chars?
      {
        // CHANGE THIS LINE
        int ch1x = 200,
            ch1y = 200,
            ch2x = 600,
            ch2y = 200; // Where they are idk how big they are and where they should go
        String tagCopy =
            tag; // Need to make a copy because we still need to access the background component
        // later
        tagCopy =
            tagCopy.substring(
                tag.indexOf("T")); // gets the rest of the string after the tag of where they are
        String ch1 = tagCopy.substring(1, 4); // gets the name of the first character file
        url = getClass().getResource(ch1 + ".png");
        c1 = ImageIO.read(url); // reads in the first character image
        String ch2 = tagCopy.substring(4); // second char file
        c2 = ImageIO.read(url); // reads in
        g.drawImage(c1, ch1x, ch1y, null); // draws c1
        g.drawImage(c2, ch2x, ch2y, null); // draws c2
        url = getClass().getResource(ch2 + ".png");
      } else // only one char
      {
        // CHANGE THIS LINE
        int cx = 400, cy = 200; // location of the char
        String ch = tag.substring(tag.indexOf('C')); // gets name of char
        url = getClass().getResource(ch + ".png");
        c = ImageIO.read(url); // reads in
        g.drawImage(c, cx, cy, null); // draws c
      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
Example #19
0
  public void run() {
    Thread me = Thread.currentThread();
    while (getSize().width <= 0) {
      try {
        anim.sleep(500);
      } catch (InterruptedException e) {
        return;
      }
    }

    Graphics2D g2d = null;
    Graphics2D BufferG2D = null;
    Graphics2D ScreenG2D = null;
    BasicStroke solid = new BasicStroke(9.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 9.0f);
    GeneralPath gp = new GeneralPath(GeneralPath.WIND_NON_ZERO);
    int rule = AlphaComposite.SRC_OVER;
    AlphaComposite opaque = AlphaComposite.SrcOver;
    AlphaComposite blend = AlphaComposite.getInstance(rule, 0.9f);
    AlphaComposite set = AlphaComposite.Src;
    int frame = 0;
    int frametmp = 0;
    Dimension oldSize = getSize();
    Shape clippath = null;
    while (anim == me) {
      Dimension size = getSize();
      if (size.width != oldSize.width || size.height != oldSize.height) {
        img = null;
        clippath = null;
        if (BufferG2D != null) {
          BufferG2D.dispose();
          BufferG2D = null;
        }
        if (ScreenG2D != null) {
          ScreenG2D.dispose();
          ScreenG2D = null;
        }
      }
      oldSize = size;

      if (img == null) {
        img = (BufferedImage) createImage(size.width, size.height);
      }

      if (BufferG2D == null) {
        BufferG2D = img.createGraphics();
        BufferG2D.setRenderingHint(
            RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT);
        BufferG2D.setClip(clippath);
      }
      g2d = BufferG2D;

      float[] ctrlpts;
      for (int i = 0; i < animpts.length; i += 2) {
        animate(animpts, deltas, i + 0, size.width);
        animate(animpts, deltas, i + 1, size.height);
      }
      ctrlpts = animpts;
      int len = ctrlpts.length;
      gp.reset();
      int dir = 0;
      float prevx = ctrlpts[len - 2];
      float prevy = ctrlpts[len - 1];
      float curx = ctrlpts[0];
      float cury = ctrlpts[1];
      float midx = (curx + prevx) / 2.0f;
      float midy = (cury + prevy) / 2.0f;
      gp.moveTo(midx, midy);
      for (int i = 2; i <= ctrlpts.length; i += 2) {
        float x1 = (midx + curx) / 2.0f;
        float y1 = (midy + cury) / 2.0f;
        prevx = curx;
        prevy = cury;
        if (i < ctrlpts.length) {
          curx = ctrlpts[i + 0];
          cury = ctrlpts[i + 1];
        } else {
          curx = ctrlpts[0];
          cury = ctrlpts[1];
        }
        midx = (curx + prevx) / 2.0f;
        midy = (cury + prevy) / 2.0f;
        float x2 = (prevx + midx) / 2.0f;
        float y2 = (prevy + midy) / 2.0f;
        gp.curveTo(x1, y1, x2, y2, midx, midy);
      }
      gp.closePath();

      g2d.setComposite(set);
      g2d.setBackground(backgroundColor);
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);

      if (bgChanged || bounds == null) {
        bounds = new Rectangle(0, 0, getWidth(), getHeight());
        bgChanged = false;
      }
      // g2d.clearRect(bounds.x-5, bounds.y-5, bounds.x + bounds.width + 5, bounds.y + bounds.height
      // + 5);
      g2d.clearRect(0, 0, getWidth(), getHeight());

      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.setColor(outerColor);
      g2d.setComposite(opaque);
      g2d.setStroke(solid);
      g2d.draw(gp);
      g2d.setPaint(gradient);

      if (!bgChanged) {
        bounds = gp.getBounds();
      } else {
        bounds = new Rectangle(0, 0, getWidth(), getHeight());
        bgChanged = false;
      }
      gradient =
          new GradientPaint(
              bounds.x,
              bounds.y,
              gradientColorA,
              bounds.x + bounds.width,
              bounds.y + bounds.height,
              gradientColorB,
              true);
      g2d.setComposite(blend);
      g2d.fill(gp);

      if (g2d == BufferG2D) {
        repaint();
      }
      ++frame;
      Thread.yield();
    }
    if (g2d != null) {
      g2d.dispose();
    }
  }