Swing做出异型登录窗口

在程序中依次设置以下几个参数:

  • 设置窗口完全透明:AWTUtilities.setWindowOpaque(frame, false);
  • 设置窗口无边缘:frame.setUndecorated(true);
  • 设置窗口的ContentPane为要显示的Pane:frame.setContentPane(myPane);
  • 在myPane中放置具体要显示的内容,也可以重载paint方法进行Java2D绘制。这些paint会直接发生在桌面背景上。
通过上面方法,可以做一个任意大小、任意位置的window,在相应的桌面位置上随意显示Swing组件,或做任意Java2D画图。比如下面小例子可以在屏幕上直接画一个红色的立体矩形,而没有显示窗口:

import com.sun.awt.AWTUtilities;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.setBounds(500, 500, 300, 300);
        AWTUtilities.setWindowOpaque(frame, false);

        JPanel pane = new JPanel() {

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

                g.setColor(Color.red);
                g.fill3DRect(10, 10, 100, 100, true);
            }
        };

        frame.setContentPane(pane);

        frame.setVisible(true);
    }
}
运行效果如下图:

窗口的拖拽移动

窗口不再规则,窗口标题栏不再出现,如何移动窗口?按照其他类似软件的习惯做法,应当允许用鼠标直接拖拽窗体任意位置进行窗口移动。做一个鼠标监听器对窗口中的元素进行拖动监听,对窗口进行相应拖动距离的移动:

private MouseAdapter moveWindowListener = new MouseAdapter() {

        private Point lastPoint = null;

        @Override
        public void mousePressed(MouseEvent e) {
            lastPoint = e.getLocationOnScreen();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            Point point = e.getLocationOnScreen();
            int offsetX = point.x - lastPoint.x;
            int offsetY = point.y - lastPoint.y;
            Rectangle bounds = FreeLoginUI.this.getBounds();
            bounds.x += offsetX;
            bounds.y += offsetY;
            FreeLoginUI.this.setBounds(bounds);
            lastPoint = point;
        }
};

 对窗体上的组件安装这一listener,就可以对窗口中任意元素进行拖拽,直接拖动窗体四处晃悠了。

制作渐变背景Panel

仔细观察中间的输入区域部分,其背景是有渐变设计的。其制作方法也很简单:首先让美工帮助制作一个一个像素宽、整个panel高度的小图片作为素材;然后用这个图片创建纹理Paint;最后用这个纹理对真个panel进行fill。

<span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">private JPanel inputPane = new JPanel() {


        private String backgroundImageURL = FreeUtil.getImageURL("login_background.png");
        private TexturePaint paint = FreeUtil.createTexturePaint(backgroundImageURL);


        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setPaint(paint);
            g2d.fillRect(0, 0, this.getWidth(), this.getHeight());
        }
</span></span><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"><span style="font-size: 14px;">    };</span><span style="font-size:18px;">
</span></span></span></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;"><span style="line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"></span></span><pre name="code" class="java"><p style="font-size: 14px; margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;">肆虐你的桌面:六月飘雪!
既然窗户纸捅破了,在桌面上就随意折腾吧。这几天窗外酷热难耐,咱们就来个桌面飘雪,也许可以望梅止渴,带来丝丝清凉吧!
 
先准备一个雪花的png透明图片,然后在桌面上随机生成50个雪花坐标,每次paint让每个雪花的左右略微抖一下(snowX[i] += TWaverUtil.getRandomInt(5) - 3),垂直距离下坠5像素(snowY[i] += 5),再旋转个小角度。然后,用一个线程不停的repaint窗口。
 
雪花png图片:
 
<img alt="" src="http://dl.iteye.com/upload/attachment/274324/d1c5c45e-8f3d-3089-b2fe-0efba12deed2.png" style="border: 0px;" />
程序代码如下:</p><div style="font-size: 14px;">public class TestSnow {


    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        frame.setAlwaysOnTop(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(true);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        AWTUtilities.setWindowOpaque(frame, false);


        final JPanel pane = new JPanel() {


            private int[] snowX = null;
            private int[] snowY = null;
            private int[] angles = null;
            private int count = 50;


            @Override
            public void paint(Graphics g) {
                super.paint(g);
                Rectangle bounds = frame.getBounds();
                if (snowX == null) {


                    snowX = new int[count];
                    for (int i = 0; i < snowX.length; i++) {
                        snowX[i] = TWaverUtil.getRandomInt(bounds.width);
                    }
                    snowY = new int[count];
                    for (int i = 0; i < snowY.length; i++) {
                        snowY[i] = TWaverUtil.getRandomInt(bounds.height);
                    }
                    angles = new int[count];
                    for (int i = 0; i < snowY.length; i++) {
                        angles[i] = TWaverUtil.getRandomInt(360);
                    }
                }


                Graphics2D g2d = (Graphics2D) g;
                Image image = TWaverUtil.getImage("/free/test/snow.png");
                for (int i = 0; i < count; i++) {
                    snowX[i] += TWaverUtil.getRandomInt(5) - 3;
                    snowY[i] += 5;
                    angles[i] += i / 5;
                    snowY[i] = snowY[i] > bounds.height ? 0 : snowY[i];
                    angles[i] = angles[i] > 360 ? 0 : angles[i];
                    int x = snowX[i];
                    int y = snowY[i];
                    int angle = angles[i];
                    g2d.translate(x, y);
                    double angleValue = Math.toRadians(angle);
                    g2d.rotate(angleValue);
                    g2d.drawImage(image, 0, 0, null);
                    g2d.rotate(-angleValue);
                    g2d.translate(-x, -y);
                }
            }
        };


        frame.setContentPane(pane);
        frame.setVisible(true);
        Thread thread = new Thread() {


            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                    pane.repaint();
                }
            }
        };


        thread.start();
    }
}</div><div><span style="font-size:24px;color:#ff0000;">注:程序中用到的第三方jar为:twaver.jar  looks.2.1.4.jar</span></div><div><span style="font-size:24px;color:#ff0000;">
</span></div>
<p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">如果愿意折腾,还可以修改代码中的:</p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"> </p><ul style="margin: 0px 0px 1.5em; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">private int count = 50,调整雪花的数量;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改angles[i] += i / 5,调整雪花翻滚的速度;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改snowY[i] += 5,调整雪花下坠的速度;</li><li style="margin: 0px 0px 0.25em 30px; padding: 0px;">修改snowX[i] += TWaverUtil.getRandomInt(5) – 3,调整雪花左右摆动的速度;</li></ul><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);"> </p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">别说你不知道怎么结束程序啊,不会Alt+F4的话,你这个程序员肯定不合格了。</p><h2 style="line-height: 1.5em; margin: 0px 0px 0.5em; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; background-color: rgb(239, 239, 239);">秘密背后的秘密</h2><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px; line-height: 25.2000007629395px; background-color: rgb(239, 239, 239);">当把透明窗口Frame设置特别大以后(例如10000*10000),你会发现不但界面变得极其缓慢,而且还会内存溢出。Sun的秘密不言自明了:还是使用了BufferedImage。否则,鼠标点击你画的椭圆或桌面的图标,它如何知道是点击了窗体,还是操作了桌面?只能生成内存图片,在里面进行像素判断了。要挖掘再深入的秘密,我也不清楚了,自己继续探索吧!</p>

 
 

猜你喜欢

转载自blog.csdn.net/ytlcainiao/article/details/45953443
今日推荐