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就可以。

转载于:https://www.cnblogs.com/IamThat/archive/2013/03/13/2957721.html

重写JFrame的扩大 缩小 关闭按钮 以及菜单等相关推荐

  1. CSS绘制放大缩小关闭按钮

    如上图所示,使用CSS 绘制上述三个按钮: <template><div class="windowAction"><button class=&qu ...

  2. java jframe添加面板_JFrame添加组件的两种方式

    对JFrame添加组件有两种方式:1) 用getContentPane()方法获得JFrame的内容面板,再对其加入组件:frame.getContentPane().add(childCompont ...

  3. JFrame和Frame的区别

    在AMT组件中分为两大类,这两类的基类分别是Component和MenuComponent,其中,MenuComponent是所有与菜单相关组件的父类,Component则是除菜单外其他AMT组件的父 ...

  4. Java界面命名_java中用setTitel和JFrame给窗体命名的区别

    展开全部 下面是一个计算器的例子: import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayou ...

  5. android菜单(menu)资源

    一. 菜单资源通常放在res/menu目录下,菜单资源是的根元素通常是<menu></menu>标记,在该标记下可以包含以下两个元素. 1.<item></i ...

  6. VC++学习(6):菜单编程

    1.       MFC中的顶层菜单默认为弹出菜单(Pop-up),它是不能用来作命令响应的,当取消Pop-up选项后可接受命令响应. 2.       消息的分类:标准消息,命令消息,通告消息. [ ...

  7. cocos2d-x 中菜单类

    菜单相关类包含:菜单类和菜单项类,菜单类图,从类图可见Menu类继承于Layer. 菜单项类图,从图中可见所有的菜单项都是从BaseMenuItem继承而来的,BaseMenuItem是抽象类,具体使 ...

  8. Arcgis开发系列2 - 修改arcgis infowindow 放大和缩小的模板

    在使用arcgis自带的infowindow弹出的详情的时候会有放大和缩小的infowindow显示内容不同的需求,现在此做出处理方法1.设置infowindow模板 (2个table第一个是小的in ...

  9. 修改arcgis infowindow 放大和缩小的模板

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/bitree1/article/details/74029768 在使用arcgis自带的infowi ...

最新文章

  1. 一个JDK线程池BUG引发的GC机制思考
  2. iView 近期的更新,以及那些“不为人知”的故事
  3. 反序列化层遍历二叉树
  4. C语言指针变量的定义和使用
  5. Linux上开启TUN
  6. 多线程 thread java_java Thread 多线程
  7. 使用audit工具常规命令监控系统访问文件
  8. bzoj 5094: 硬盘检测(概率)
  9. java webp 图片处理_Java处理Webp图片格式转换的示例代码
  10. java isbn_Java ISBN formating
  11. 解决联想笔记本 FN键不起作用的方法
  12. Finclip小程序宿主环境与微信小程序宿主环境
  13. 新概念英语第二册61-96课(转)
  14. 给定出生年月日及现在年月日,计算天数
  15. QT从入门到入土(三)——信号和槽机制
  16. 网络系统管理技能大赛知识点一
  17. canal的INVALID_TOPIC_EXCEPTION问题
  18. selenium_Selenium4 Alpha –期望什么?
  19. android usb触摸屏idc实现触摸唤醒
  20. iPhone(IOS10)忘记了访问限制的密码该怎么办?

热门文章

  1. docker部署下的nginx负载均衡时,无法获取真实ip的问题
  2. C语言再学习 -- 存储类型关键字
  3. Docker操作命令详解
  4. java 内部类_Java——内部类详解
  5. LOJ #516. 「LibreOJ β Round #2」DP 一般看规律
  6. ws.v6p.coindex.php,php_168_v6目录
  7. grep检索关键字的命令_linux系统中java线上问题常用排查命令
  8. python list查找元素下标_Python 查找list中的某个元素的所有的下标方法
  9. vb6 打印选项对话框_办公必备技能,Word打印问题及解决方案全在这,轻松解决打印难题...
  10. matlab优化应用