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)); }
// 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); } }
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); }
@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); } } }
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); } } }
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(); } }
/** 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); } }
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(); } }
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]++; } } } }
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 } }
/** * 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&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); } }
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(); } }
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(); } }