zoukankan      html  css  js  c++  java
  • 重写JFrame的扩大 缩小 关闭按钮 以及菜单等

    http://hi.baidu.com/righttoleft/item/6cfbcef9e2005f633c148563

    重写JFrame标题、按钮等

    其实标题并不准确,但是一般人们都这样称呼它们为标题。文章最后贴了最新发现的bug

    其实是JFrame的memuBar部分。

    JFram由充满布局的glassPanel(负责切屏大小事件)和充满布局的JComponent组成。

    JComponent负责添加组件。JComponent由memuBar和下部JComponent组成.

    当没有memuBar时下部JComponent充满。

    此文讨论的其实就是修改 memuBar部分。通常包含一个popupMemu 、标题、最小化、最大化、关闭按钮。

    由于java内部JFrame的实现机制,JFrame的memuBar 是 MetalTitlePane类型,这个类是不支持外部访问的。 所以要修改 memuBar 只能另谋出路。我是按如下方式实现的:

    在 JFrame内加 如下代码(其中全屏时会把任务栏也覆盖了,可以不使用JFrame状态,改用size来解决)

    this.setUndecorated(true); // 去掉窗口的装饰    this.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);// 采用指定的窗口装饰风格    JLayeredPane jpanel2 = (JLayeredPane) this.rootPane.getComponents()[1];       JComponent bar = (JComponent) jpanel2.getComponent(1);//获取MetalTitlePane,只能强转为上一级    System.out.println(jpanel2.getComponent(1));

    //我为了采用这三个按钮的样式,所以沿袭了系统的。 也可以不获取,在新的jpanel中自己定义。    JButton minBtn = (JButton) bar.getComponent(1);//最小化按钮    JButton maxBtn = (JButton) bar.getComponent(2);//最大化按钮    JButton closeBtn = (JButton) bar.getComponent(3);//关闭按钮

       jpanel2.remove(1);//删除MetalTitlePane

    //新的顶部jpanel,取代了MetalTitlePane的位置。

       TopBarPanel topJpanel = new TopBarPanel(minBtn, maxBtn, closeBtn);

       jpanel2.add(topJpanel, 1);

    注意:TopBarPanel 没有任何事件,内部按钮也没有事件,这些都需要自己添加:

    TopBarPanel 代码如下 ,有些代码没有进一步提精,可以自己提纯。

    /* * Copyright (c) 2010 CCX(China) Co.,Ltd. All Rights Reserved. * * This software is the confidential and proprietary information of * CCX(China) Co.,Ltd. ("Confidential Information"). * It may not be copied or reproduced in any manner without the express  * written permission of CCX(China) Co.,Ltd. * * @author wangyx * Date: 2010-5-25 上午10:29:25 */ package com.ccxc.indexfuture.frame;

    import java.awt.Color; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.InputStream;

    import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel;

    import com.ccxc.indexfuture.service.FrameMotionListener;

    /* * 最顶部的标题和按钮panel,自适应窗口拖拽宽度 */ @SuppressWarnings("serial") public class TopBarPanel extends JPanel {

    JButton minBtn = null; JButton maxBtn = null; JButton closeBtn = null;

    private Integer oldX; private Integer oldY;

    FrameMotionListener frameListener; // 主frame JFrame frame;

    /** * Create the application */ public TopBarPanel(JButton minbtn, JButton maxbtn, JButton closebtn) {    super();    try {     // 初始化最小化、最大化、关闭按钮     this.minBtn = minbtn;     this.maxBtn = maxbtn;     this.closeBtn = closebtn;     jbInit();    } catch (Throwable e) {     e.printStackTrace();    }

    }

    // 重绘事件 public void paintComponent(Graphics g) {    super.paintComponent(g);    Dimension dimension = this.getParent().getSize(); // 获得屏幕大小    // 获取原窗口的宽高    int w = this.getWidth();    int h = this.getHeight();    // 获取改变的宽度差    double width = dimension.getWidth() - w;    // 设置窗口和屏幕宽度相同    dimension.setSize(dimension.getWidth(), h);    this.setSize(dimension);

       // 更改按钮位置    int childNum = this.getComponentCount();    for (int i = 0; i < childNum; i++) {     JComponent child = (JComponent) this.getComponent(i);     // 获取右侧的按钮     if (child instanceof JButton) {      Point p = child.getLocation();      // 修改按钮横向位置      p.setLocation(p.getX() + width, p.getY());      child.setLocation(p);      // child.revalidate();     }    }    this.revalidate();    // } }

    // 初始化面板的属性 private void jbInit() throws Exception {    System.currentTimeMillis();    this.setBounds(0, 0, 1000, 22);    this.setBackground(Color.BLACK);

       this.add(minBtn);    this.add(minBtn);    this.add(minBtn);

       this.setLayout(null);    // 读取背景图片    InputStream in = getClass().getResourceAsStream("zcx.jpg");    if (in == null) {     System.err.println("Image not found.");     return;    }       byte[] buffer = new byte[in.available()];    in.read(buffer);    Image m_image = Toolkit.getDefaultToolkit().createImage(buffer);    // 加图片    JLabel img = new JLabel(new ImageIcon(m_image));    // 加背景    JLabel jb = new JLabel("中诚信金融信息服务平台");       // 图片位置    img.setBounds(1, 1, 33, 20);    // 标题位置    jb.setBounds(35, 0, 300, 20);    jb.setForeground(Color.white);

       // img.setOpaque(false);

       this.add(img);    this.add(jb);

       // 按钮位置    minBtn.setBounds(923, 1, 22, 20);    this.add(minBtn);    maxBtn.setBounds(948, 1, 22, 20);    maxBtn.setText("");    this.add(maxBtn);    closeBtn.setBounds(973, 1, 22, 20);    this.add(closeBtn);

       frame = MainMenu.getMapJFrame().get("showFrame");

       // 注册主frame拖揣事件    addFrameMotionEvent();    // 注册最大化、最小化、和关闭按钮事件    buttonEvent();    // 注册双击本面板 事件    myDbClickedEvent(); }

    // 窗口追随鼠标按住移动事件 private void addFrameMotionEvent() {    final JPanel this_Panel = this;    // 添加鼠标点击事件    this.addMouseListener(new MouseAdapter() {

        public void mousePressed(MouseEvent e) {      // 获取鼠标位置      oldX = e.getX();      oldY = e.getY();      // 添加鼠标拖动事件      frameListener = new FrameMotionListener(oldX, oldY);      this_Panel.addMouseMotionListener(frameListener);     }

       });

       this.addMouseListener(new MouseAdapter() {     // 删除鼠标拖动事件     public void mouseReleased(MouseEvent e) {      this_Panel.removeMouseMotionListener(frameListener);     }

       }); }

    private void buttonEvent() {

       // 最小化按钮事件    minBtn.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent e) {      // 最小化操作      frame.setState(Frame.ICONIFIED);     }    });

       // 最大化按钮事件    maxBtn.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent e) {      changeFrameState() ;     }    });

       // 关闭按钮事件    closeBtn.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent e) {      // 关闭操作      System.exit(0);     }    }); }

    // 双击面板更改窗口状态事件 private void myDbClickedEvent() {    this.addMouseListener(new MouseAdapter() {

        public void mouseClicked(MouseEvent e) {      if(e.getClickCount() == 2 ){       changeFrameState();       }     }    }); }
    //修改frame显示状态 private void changeFrameState(){    if (frame.getExtendedState() == Frame.MAXIMIZED_BOTH) {     // 恢复操作     frame.setExtendedState(Frame.NORMAL);    } else {     // 最大化操作     frame.setExtendedState(Frame.MAXIMIZED_BOTH);    } } }

    //主JFrame事件类

    /* * Copyright (c) 2010 CCX(China) Co.,Ltd. All Rights Reserved. * * This software is the confidential and proprietary information of * CCX(China) Co.,Ltd. ("Confidential Information"). * It may not be copied or reproduced in any manner without the express  * written permission of CCX(China) Co.,Ltd. * * @author wangyx * Date: 2010-5-25 下午01:35:01 */ package com.ccxc.indexfuture.service;

    import java.awt.Point; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener;

    import javax.swing.JFrame;

    import com.ccxc.indexfuture.frame.MainMenu;

    /** * 添加主frame的鼠标拖揣移动事件 * @author wangyx *  */ public class FrameMotionListener implements MouseMotionListener {

    private JFrame frame; private Integer oldX; private Integer oldY;

    public FrameMotionListener(Integer oldX, Integer oldY) {    //获取主frame    frame = MainMenu.getMapJFrame().get("showFrame");    //拖动前的鼠标位置    this.oldX = oldX;    this.oldY = oldY; }

    //拖动事件 @Override public void mouseDragged(MouseEvent e) {    int newX = e.getX();    int newY = e.getY();    //后去frame的原位置是    Point p = frame.getLocation();    //更新frame位置    p.setLocation(p.getX() + newX - oldX, p.getY() + newY - oldY);    frame.setLocation(p); }

    @Override public void mouseMoved(MouseEvent e) { }

    }

    补:今天发现最大化按钮和双击面板之间切换窗口大小时会有冲突,等有时间改下,换成修改JFrame size,另做static变量来保存原来的size就可以。

    I'm falling off the sky all alone.The courage inside is gonna break the fall. Nothing can dim my light within. I am That I am 程序 = 数据结构 + 算法
  • 相关阅读:
    JS之函数声明与表达式
    任重道远!
    Java_Notes01
    Android_Application Fundamentals
    Android_Activity
    Android
    Linux下的实模式和保护模式
    spring注解原理
    开启aix SFTP日志 是否和链接SFTP有关呢
    Apache版本兼容性问题
  • 原文地址:https://www.cnblogs.com/IamThat/p/2957721.html
Copyright © 2011-2022 走看看