Java 自定义窗体(标题栏、窗体背景)
最近在书上看到这篇文章,觉得挺有意思。与大家分享一下,具体可以参见明日科技出版的《Java经典编程300例》。
默认情况下,我们用java设计的界面窗体是这样的:

默认的标题栏、最大化、最小化、关闭按钮、窗体边框。
如何自定义窗体达到如下效果呢?

大致说下代码要点:
- 设置窗体的Undecorated属性为true,阻止窗体采用本机系统修饰,这样窗体就没有标题栏和边框了。
- 设计背景面板类。BackgroundPanel extends JPanel。
- 窗体面板添加标题栏面板,位置在上方。
- 标题栏面板添加背景面板显示标题栏图片、标题栏面板添加面板用于放置最大化、最小化、关闭按钮。
- 窗体面板添加背景面板在中间。contentPane.add(mianPanel,BorderLayout.Center);
- 添加按钮响应、添加标题栏拖动代码。
代码:
首先是带背景图片面板类:
package cn.chengmaoning.customframe;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
public class BackgroundPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = -898997756345637309L;
private Image image;
/**
* Constructor
*/
public BackgroundPanel() {
super();
setOpaque(false);
setLayout(null);
}
/**
* @param image
* 要设置的 image
*/
public void setImage(Image image) {
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
if (image != null) {
int width = getWidth();// 获取组件大小
int height = getHeight();
g.drawImage(image, 0, 0, width, height, this);// 绘制图片与组件大小相同
}
super.paintComponent(g);// 执行超类方法
}
}
其次再是主类:
package cn.chengmaoning.customframe;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.jws.Oneway;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class ControlFormStatus extends JFrame {
/**
*
*/
private static final long serialVersionUID = -2214759764324605473L;
private JPanel contentPane;
private Point pressedPoint;
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// TODO 自动生成的方法存根
try {
ControlFormStatus frame = new ControlFormStatus();
frame.setVisible(true);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
});
}
/**
* Constructor
*/
public ControlFormStatus(){
setUndecorated(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(null);
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
BackgroundPanel topPanel = new BackgroundPanel();
topPanel.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e){
do_topPanel_mouseDragged(e);
}
});
topPanel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
do_topPanel_mousePressed(e);
}
});
Image centerImage = new ImageIcon(getClass().getResource("frameTop.png")).getImage();
Dimension dimension = new Dimension(centerImage.getWidth(this), centerImage.getHeight(this));
topPanel.setPreferredSize(dimension);
topPanel.setImage(centerImage);
contentPane.add(topPanel,BorderLayout.NORTH);
topPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 5, 5));
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(60, 22));
panel.setOpaque(false);
topPanel.add(panel);
panel.setLayout(new GridLayout(1, 0, 0, 0));
JButton button = new JButton("");
button.setRolloverIcon(new ImageIcon(ControlFormStatus.class.getResource("minBH.jpg")));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
do_button_actionPerformed(e);
}
});
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setIcon(new ImageIcon(ControlFormStatus.class.getResource("minB.jpg")));
panel.add(button);
JToggleButton button_1 = new JToggleButton("");
button_1.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
// TODO 自动生成的方法存根
do_button_1_itemStateChanged(e);
}
});
button_1.setRolloverIcon(new ImageIcon(ControlFormStatus.class.getResource("maxBH.jpg")));
button_1.setRolloverSelectedIcon(new ImageIcon(ControlFormStatus.class.getResource("maxBH.jpg")));
button_1.setIcon(new ImageIcon(getClass().getResource("maxB.jpg")));
button_1.setContentAreaFilled(false);
button_1.setBorderPainted(false);
button_1.setFocusPainted(false);
panel.add(button_1);
JButton button_2 = new JButton("");
button_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
do_button_2_actionPerformed(e);
}
});
button_2.setRolloverIcon(new ImageIcon(getClass().getResource("closeBH.jpg")));
button_2.setIcon(new ImageIcon(getClass().getResource("closeB.jpg")));
button_2.setFocusPainted(false);
button_2.setContentAreaFilled(false);
button_2.setBorderPainted(false);
panel.add(button_2);
BackgroundPanel baclBackgroundPanel_1 = new BackgroundPanel();
Image topImage = new ImageIcon(getClass().getResource("frameCenter.png")).getImage();
baclBackgroundPanel_1.setImage(topImage);
contentPane.add(baclBackgroundPanel_1, BorderLayout.CENTER);
}
protected void do_button_2_actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
dispose();
}
protected void do_button_1_itemStateChanged(ItemEvent e) {
// TODO 自动生成的方法存根
if (e.getStateChange() == ItemEvent.SELECTED) {
setExtendedState(MAXIMIZED_BOTH);
} else {
setExtendedState(NORMAL);
}
}
protected void do_button_actionPerformed(ActionEvent e) {
// TODO 自动生成的方法存根
setExtendedState(ICONIFIED);
}
protected void do_topPanel_mousePressed(MouseEvent e) {
// TODO 自动生成的方法存根
pressedPoint = e.getPoint();
}
protected void do_topPanel_mouseDragged(MouseEvent e) {
// TODO 自动生成的方法存根
Point point = e.getPoint();
Point locationPoint = getLocation();
int x = locationPoint.x + point.x - pressedPoint.x;
int y = locationPoint.y + point.y - pressedPoint.y;
setLocation(x, y);
}
}
代码中用到的图片如下:(我不知道有什么更好的方法可以把图片保存到这篇文章里,所以只有贴到这里了,试验的同学可以直接另存图片到本机,放置到与.java相同路径下即可)








Java 自定义窗体(标题栏、窗体背景)的更多相关文章
- WPF 之 自定义窗体标题栏
在WPF中自定义窗体标题栏,首先需要将窗体的WindowStyle属性设置为None,隐藏掉WPF窗体的自带标题栏.然后可以在窗体内部自定义一个标题栏. 例如,标题栏如下: <WrapPanel ...
- WinForm拖动没有标题栏窗体的方法
建立窗体的名称修改为:Form_HoverTree 文后附有源码下载. 主要代码: Point _HoverTreePosition; public Form_HoverTree() { Initia ...
- 【转】【C#】C#重绘windows窗体标题栏和边框
摘要 windows桌面应用程序都有标准的标题栏和边框,大部分程序也默认使用这些样式,一些对视觉效果要求较高的程序,如QQ, MSN,迅雷等聊天工具的样式则与传统的windows程序大不相同,其中迅雷 ...
- WPF修改窗体标题栏的颜色
WPF程序通常情况下没办法修改窗体标题栏的样式,包括标题栏的背景颜色. 不过借助一个叫Fluent.Ribbon的第三方控件,貌似可以修改标题栏的背景颜色. 可以通过NuGet来安装这个控件:Inst ...
- C#之移动无标题栏窗体功能的实现!...
为实现移动无标题栏窗体的功能,我从网上寻找.整理了以下资料,以备不时之需: 该方法适用于有标题栏和无标题栏窗体,适用于窗体内控件,当然 Form 也不例外, 只须添加 MouseDown.MouseM ...
- Delphi组件开发-在窗体标题栏添加按钮(使用MakeObjectInstance(NewWndProc),并处理好多消息)
这是一个在窗体标题栏添加自定义按钮的组件(TTitleBarButton)开发实例,标题栏按钮组件TTitleBarButton以TComponent为直接继承对象,它是一个可以在窗体标题栏上显示按钮 ...
- C# 移动无标题栏窗体的几种方法
第一种,手工移动. 该方法根据鼠标位置实现窗体的移动.网上有很多相关的例子,这里不再多讲. 第二种,调用系统API原理:是当鼠标左键按下时,让系统认为是在标题栏按下的.这里我们用到了winapi里的W ...
- C#自定义运行时窗体设计器Runtime FormDesigner
写在前面:因为业务的需要,有时会使用到自定义运行时窗体设计器Runtime FormDesigner,实现的功能,就是IDE设计器的简化.设想一下,如果可以在程序运行时,再设计一个Form,然后编译代 ...
- C#实现无标题栏窗体点击任务栏图标正常最小化或还原的解决方法
对于无标题栏窗体,也就是FormBorderStyle等于System.Windows.Forms.FormBorderStyle.None的窗体,点击任务栏图标的时候,是不能象标准窗体那样最小化或还 ...
随机推荐
- vue从入门到精通之【vuex】(七)
vue从入门到精通之[vuex](七) vuex一个公用的大仓库,Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架. Vuex 实现了一个单向数据流,在全局拥有一个 state 存放数据, ...
- 【】JSON介绍
0.说明 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写. 同时也易于机器解析和生成. 它是基于JavaScript Programm ...
- 深入浏览器工作原理和JS引擎(V8引擎为例)
浏览器工作原理和JS引擎 1.浏览器工作原理 在浏览器中输入查找内容,浏览器是怎样将页面加载出来的?以及JavaScript代码在浏览器中是如何被执行的? 大概流程可观察以下图: 首先,用户在浏览器搜 ...
- Go的日志库go-logging
配置文件config.yaml log: prefix: '[MY-LOG] ' log-file: true stdout: 'DEBUG' file: 'DEBUG' config/config. ...
- vue爬坑之路(webpack 配置篇)
在vue cli下 1.npm run dev 打开浏览器在config的index.js中修改autoOpenBrowser为true 关闭sourcemap productionSourceMap ...
- less与sass的区别
在介绍less和sass的区别之前,我们先来了解一下他们的定义: 一.Less.Sass/Scss是什么? 1.Less: 是一种动态样式语言. 对CSS赋予了动态语言的特性,如变量.继承.运算.函数 ...
- Vulnhub系列:Os-hackNos
0x01环境搭建 靶机链接: https://www.vulnhub.com/entry/hacknos-os-hacknos,401/发布日期: 2019.11.27靶机描述: 描述 难度:容易中级 ...
- 【刷题-LeetCode】230. Kth Smallest Element in a BST
Kth Smallest Element in a BST Given a binary search tree, write a function kthSmallest to find the k ...
- Superset SSO改造和自定义宏命令
目录 背景 关于Superset 需要解决的问题 定制化改造 准备环境 改造OAuth SSO 安装依赖 配置SSO 添加自定义的SecurityManager 运行一下吧 自定义宏命令 开启配置 添 ...
- pytest文档5-参数化parametrize
pytest.mark.parametrize装饰器可以实现测试用例参数化. parametrizing 1.这里是一个实现检查一定的输入和期望输出测试功能的典型例子 # content of tes ...