Java创建透明与任意形状窗口
一: Java 2D图形基础知识
自从Java Swing发布以来,Java的图形能力得到了很大的提升,JDK6的高级版本开始支持创
建自定义形状的JFrame,结合Java 2D图形的相关API,可以实现任意形状JFrame的创建。当
前JAVA 2提供可以创建的基本形状如下:
当前Java提供的对2D图形的主要操作有裁剪和路径覆盖,适当的运用Java 2D与Swing的其
他相关API,可以创建出任意形状的JFrame。
二:API支持透明和自定义形状
从JDK6的release 10开始支持设置透明和自定义形状,支持的对象有Swing的JFrame, JDialog,
AWT的Frame.以及所以继承java.awt.Window的子类。
Windows的透明效果又分为两类,简单的透明效果和基于像素位的透明效果。简单透明效果使
用alpha来设置所有的象素位,值越小越透明,最小值是完全透明,最大值代表完全不透明
(opaque)windows, 基于像素为的透明效果需要通过以下API来启用:
AWTUtilities.setWindowOpaque (frame, false);
对于透明度和形状的设定都是通过Java的反射机制完成调用,在JDK的官方网站有一个很好的Demo里面有个AWTUtilitiesWrappe类是一个很好的示例.
三:一个可以改变自身形状与透明效果的JFrame
程序的主要功能是选择你想要的形状,然后点击【OK】按钮,应用程序的窗口随之改变
点击【Cancel】按钮将推出程序,移动鼠标到窗口上面,可以拖动窗口程序。
涉及到Swing组件有JFrame, JPanel, JButton, JComboBox
组件的位置放置使用了绝对定位的方式,需要调用setLayout(null)来声明绝对定位方式
程序启动的运行效果如下:
选择 Circle并点击【OK】按钮以后的效果如下:
选择 Area并点击【OK】按钮以后的效果如下:
主要的代码为JCustomFrame
[java] view
plaincopy
importjava.awt.BorderLayout;
importjava.awt.Dimension;
importjava.awt.Shape;
importjava.awt.Toolkit;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.ComponentAdapter;
importjava.awt.event.ComponentEvent;
importjava.awt.geom.Area;
importjava.awt.geom.Ellipse2D;
importjava.awt.geom.RoundRectangle2D;
importjava.io.IOException;
importjava.util.logging.Level;
importjava.util.logging.Logger;
importjavax.imageio.ImageIO;
importjavax.swing.JFrame;
importjavax.swing.SwingUtilities;
importjavax.swing.UIManager;
publicclassJCustomFrameextendsJFrame {
/**
* gloomy fish
*/
privatestaticfinallongserialVersionUID = -523336873755438297L;
privateShape shape;
privatefloatalpha = 1f;
privateDimension arcSize =newDimension(50,50);
protectedstaticfinalintCIRCLE_TYPE =1;
protectedstaticfinalintRECTANGEL_TYPE =0;
protectedstaticfinalintAREA_TYPE =2;
publicJCustomFrame() {
setUndecorated(true);
setVisible(true);
setListenersForEffects();
}
publicJCustomFrame(intwidth,intheight) {
this();
setSize(width, height);
}
publicJCustomFrame(Shape shape,intwidth,intheight) {
this(width, height);
setShape(shape);
}
publicvoidsetShape(Shape shape) {
this.shape = shape;
}
publicJCustomFrame(floatalpha, Shape shape,intwidth,intheight) {
this(shape, width, height);
setAlpha(alpha);
}
publicvoidsetAlpha(floatalpha) {
this.alpha = alpha;
}
privatevoidsetListenersForEffects() {
//It is important to upadate visual effect on form resize.
addComponentListener(newComponentAdapter() {
@Override
publicvoidcomponentResized(ComponentEvent evt) {
updateFrameEffects();
}
});
}
/**
* This updates visual effects like SHAPE form and transparency. You have to
* update also shape property or it paints old shape ( if you resize
* frame without resize shape .. )
*/
publicvoidupdateFrameEffects() {
updateShape();
try{
AWTUtilitiesWrapper.setWindowShape(this, shape);
if(shape !=null) {
AWTUtilitiesWrapper.setWindowOpacity(this, alpha);
}
} catch(Exception ex) {
Logger.getLogger(JCustomFrame.class.getName()).log(Level.SEVERE,null, ex);
}
}
publicvoidupdateShape() {
if(shape ==null) {
shape = newRoundRectangle2D.Double(0d, 0d, getWidth(), getHeight(), arcSize.width, arcSize.height);
}
}
publicvoidupdateShape(inttype) {
if(type == RECTANGEL_TYPE) {
shape = newRoundRectangle2D.Double(0d, 0d, getWidth(), getHeight(), arcSize.width, arcSize.height);
} elseif(type == CIRCLE_TYPE) {
shape = newEllipse2D.Double(0,0,400,400);
} elseif(type == AREA_TYPE) {
Shape circle1 = newEllipse2D.Double(0,0,400,400);
Shape circle2 = newEllipse2D.Double(200,100,400,400);
Area area1 = newArea(circle1);
Area area2 = newArea(circle2);
area1.subtract(area2);
shape = area1;
}
}
publicvoidcenter() {
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screenSize = tk.getScreenSize();
intscreenHeight = screenSize.height;
intscreenWidth = screenSize.width;
this.setLocation((screenWidth -this.getWidth()) /2, (screenHeight -this.getHeight()) /2);
}
publicstaticvoidmain(String[] args) {
SwingUtilities.invokeLater(newRunnable() {
publicvoidrun() {
try{
// com.sun.java.swing.plaf.windows.WindowsLookAndFeel
UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
} catch(Exception e) {
}
/*These are simple custom panel generated with vidual editor of Netbeans
don't care about it, take a look only to ImagePanel inherit ( why?...)
*/
// Cool transparent Frame
finalJCustomFrame customFrame =newJCustomFrame();
customFrame.setLayout(newBorderLayout());
// create custom JPanel
finalJImagePanel panel =newJImagePanel();
java.net.URL image1 = this.getClass().getResource("ball.jpg");
try{
panel.setImage(ImageIO.read(image1));
panel.addActionListener(newActionListener() {
@Override
publicvoidactionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("OK")) {
System.out.println("Transfer now......");
customFrame.updateShape(panel.getSelectedIndex());
if(panel.getSelectedIndex() == CIRCLE_TYPE) {
customFrame.setSize(400,400);
} elseif(panel.getSelectedIndex() == AREA_TYPE) {
customFrame.setSize(400,399);// force layout Manager re-computation
} else{
customFrame.setSize(400,300);
}
} elseif(e.getActionCommand().equals("Cancel")) {
System.out.println("System Exit......");
customFrame.setVisible(false);
customFrame.dispose();
System.exit(0);
}
}
});
} catch(IOException e) {
e.printStackTrace();
}
DragBarHandler dragHandle = newDragBarHandler(customFrame);
customFrame.add(panel, BorderLayout.CENTER);
customFrame.add(dragHandle, BorderLayout.NORTH);
customFrame.setTitle("Ttranslucency JFrame");
customFrame.setSize(400,300);
customFrame.setAlpha(0.8f);
customFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
customFrame.center();
}
});
}
}
原博主留下的全部源码下载地址:http://download..net/download/jia20003/4334289