重写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就可以。
轉載于:https://www.cnblogs.com/IamThat/archive/2013/03/13/2957721.html
總結
以上是生活随笔為你收集整理的重写JFrame的扩大 缩小 关闭按钮 以及菜单等的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android中链接到百度进行搜索
- 下一篇: apue 2013-03-14