JFrame произвольной формы
Ой! Заметка есть, а русский букв нет. Обещаю, описание будет, но позже :)
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;
}
}
}
