JFrame произвольной формы
Произвольная форма окна, на примере Microsoft Word
Ой! Заметка есть, а русский букв нет. Обещаю, описание будет, но позже :)
AnyFrame.java
package ru.jcup.education.graphics.swing.anyshape; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Point; import java.awt.Shape; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import javax.swing.JFrame; import javax.swing.SwingUtilities; import ru.jcup.education.graphics.java2d.utils.LoadImage; import com.sun.awt.AWTUtilities; public class AnyFrame extends JFrame implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private BufferedImage image; AnyFrame() { this.setUndecorated(true); String imagePath = "/ru/jcup/education/graphics/resource/png/cloud.png"; image = LoadImage.loadBufferedImage(imagePath); this.setSize(image.getWidth(), image.getHeight()); Shape frameShape = ShapeUtils.prepareShape(imagePath, image); AWTUtilities.setWindowShape(this, frameShape); AWTUtilities.setWindowOpacity(this, 0.90f); AWTUtilities.setWindowOpaque(this, false); centerScreen(this); this.addMouseListener(this); this.addMouseMotionListener(this); this.setVisible(true); } @Override public void paint(Graphics g) { g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); } private void centerScreen(JFrame frame) { Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); int w = frame.getSize().width; int h = frame.getSize().height; int x = (dim.width - w) / 2; int y = (dim.height - h) / 2; frame.setLocation(x, y); } private Point start_drag; private Point start_loc; @Override public void mouseDragged(MouseEvent e) { final Point current = this.getScreenLocation(e); SwingUtilities.getRoot(this).setLocation( new Point(this.start_loc.x + current.x - this.start_drag.x, this.start_loc.y + current.y - this.start_drag.y)); } @Override public void mouseMoved(MouseEvent arg0) { } @Override public void mouseClicked(MouseEvent arg0) { } @Override public void mouseEntered(MouseEvent arg0) { } @Override public void mouseExited(MouseEvent arg0) { } @Override public void mousePressed(MouseEvent e) { this.start_drag = this.getScreenLocation(e); this.start_loc = SwingUtilities.getRoot(this).getLocation(); } @Override public void mouseReleased(MouseEvent arg0) { } private Point getScreenLocation(final MouseEvent e) { final Point cursor = e.getPoint(); final Point target_location = this.getLocationOnScreen(); return new Point(target_location.x + cursor.x, target_location.y + cursor.y); } }
ShapeUtils.java
package ru.jcup.education.graphics.swing.anyshape; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.image.BufferedImage; import java.io.DataInput; import java.io.DataOutput; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; /** * This code get from http://habrahabr.ru/post/127240/ * Method prepareShape write by Saa. * This code provide an opportunity automated create shape file at first load. */ public class ShapeUtils { public static Shape contour(final BufferedImage i) { final int w = i.getWidth(); final int h = i.getHeight(); final Area s = new Area(new Rectangle(w, h)); final Rectangle r = new Rectangle(0, 0, 1, 1); for (r.y = 0; r.y < h; r.y++) { // System.out.println(r.y + "/" + h); for (r.x = 0; r.x < w; r.x++) { if ((i.getRGB(r.x, r.y) & 0xFF000000) != 0xFF000000) { s.subtract(new Area(r)); } } } return s; } public static void save(final Shape s, final DataOutput os) throws IOException { final PathIterator pi = s.getPathIterator(null); os.writeInt(pi.getWindingRule()); System.out.println(pi.getWindingRule()); while (!pi.isDone()) { final double[] coords = new double[6]; final int type = pi.currentSegment(coords); os.writeInt(type); for (final double coord : coords) { os.writeDouble(coord); } pi.next(); } } public static Shape load(final DataInput is) throws IOException { final GeneralPath gp = new GeneralPath(is.readInt()); final double[] data = new double[6]; CYC: while (true) { final int type = is.readInt(); for (int i = 0; i < data.length; i++) { data[i] = is.readDouble(); } switch (type) { case PathIterator.SEG_MOVETO: gp.moveTo(data[0], data[1]); break; case PathIterator.SEG_LINETO: gp.lineTo(data[0], data[1]); break; case PathIterator.SEG_QUADTO: gp.quadTo(data[0], data[1], data[2], data[3]); break; case PathIterator.SEG_CUBICTO: gp.curveTo(data[0], data[1], data[2], data[3], data[4], data[5]); break; case PathIterator.SEG_CLOSE: break CYC; } } return gp.createTransformedShape(null); } public static Shape prepareShape(String imageFile, BufferedImage image) { String shapeFile = imageFile.substring(0, imageFile.lastIndexOf(".")) + ".shp"; String imageFileFull = System.getProperty("user.dir") + File.separator + "src" + shapeFile; File file = new File(imageFileFull); if (!file.exists()) { System.out.println("Компилирую изображение в форму."); System.out.println(imageFileFull); Shape shapeImage = ShapeUtils.contour(image); try { DataOutput dataOuput = new RandomAccessFile(file, "rw"); ShapeUtils.save(shapeImage, dataOuput); } catch (IOException e) { e.printStackTrace(); } return shapeImage; } else { Shape shapeImage = null; //System.out.println("Загружаю форму изображения."); DataInput dataInput; try { dataInput = new RandomAccessFile(file, "r"); shapeImage = ShapeUtils.load(dataInput); } catch (IOException e) { e.printStackTrace(); } return shapeImage; } } }