-----------------siwuxie095

工程名:CustomizeSwing

包名:com.siwuxie095.swing

类名:MyFrame.java(主类)、MyPanel.java

工程结构目录如下:

MyFrame.java(主类):

package com.siwuxie095.swing;

import java.awt.Color;

import java.awt.Component;

import java.awt.EventQueue;

import java.awt.Point;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import java.awt.event.MouseMotionAdapter;

import javax.swing.GroupLayout;

import javax.swing.GroupLayout.Alignment;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.LayoutStyle.ComponentPlacement;

import javax.swing.border.EmptyBorder;

public class MyFrame extends JFrame {

//将原本声明的 JPanel 注释掉,改为 MyPanel

//private JPanel contentPane;

private MyPanel contentPane;

//坐标:记录鼠标(mouse)的位置和窗体(JFrame)的位置

int mx,my,jfx,jfy;

//鼠标的初始位置

Point orgin=new Point();

/**

* Launch the application.

*/

public static void main(String[] args) {

EventQueue.invokeLater(new Runnable() {

public void run() {

try {

MyFrame frame = new MyFrame();

frame.setVisible(true);

} catch (Exception e) {

e.printStackTrace();

}

}

});

}

/**

* Create the frame.

*/

public MyFrame() {

//为 JFrame 添加鼠标按下和拖拽的事件:在窗体上按下鼠标可以拖拽窗体

//(如果给 contentPane 添加同样的事件是等效的)

//注意:(1)(2)是一组设置方法,(3)(4)是另一组设置方法

//(3)(4)要优于(1)(2)

addMouseListener(new MouseAdapter() {

@Override

public void mousePressed(MouseEvent e) {

// //(1)鼠标按下的瞬间在屏幕中的坐标值

// mx=e.getXOnScreen();

// my=e.getYOnScreen();

// //当前窗体的坐标值

// jfx=e.getX();

// jfy=e.getY();

//(3) 鼠标按下的时候在窗口的位置

orgin.x=e.getX();

orgin.y=e.getY();

}

});

addMouseMotionListener(new MouseMotionAdapter() {

@Override

public void mouseDragged(MouseEvent e) {

// //(2)在每一次移动鼠标时,对比移动后的坐标和移动前的坐标的差别

// //将这个差值加到窗体上即可,即鼠标移动多少,窗体就移动多少

// setLocation(jfx+(e.getXOnScreen()-mx), jfy+(e.getYOnScreen()-my));

//(4) 当鼠标拖动时获取窗口当前位置

Point p=getLocation();

// 窗口当前的位置 + 鼠标当前在窗口的位置 - 鼠标按下的时候在窗口的位置

setLocation(p.x+e.getX()-orgin.x, p.y+e.getY()-orgin.y);

}

});

//为 JFrame 添加 keyTyped 事件

//当点击 Esc 和 Space 键时退出程序

addKeyListener(new KeyAdapter() {

@Override

public void keyTyped(KeyEvent e) {

if (e.getKeyCode()==0) {

System.exit(0);

}

}

});

//设定成不使用系统自带的窗体装饰

setUndecorated(true);

//将背景设定成全透明

//前三个是 rgb 值,最后一个是透明度

//透明度为 0,整个 JFrame 就完全透明了

//因为 JFrame 被 contentPane 挡住了

//所以运行后"窗体"依然不透明,

//再去 MyPanel.java 中设置 contentPane 的透明度即可

setBackground(new Color(0,0,0,0));

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

setBounds(100, 100, 450, 300);

//将原本的实例化方式注释掉,改为 MyPanel()

//contentPane = new JPanel();

contentPane = new MyPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

setContentPane(contentPane);

JPanel panel = new JPanel();

panel.setOpaque(false);

panel.setAlignmentX(Component.LEFT_ALIGNMENT);

//下面一大段代码由系统自动生成,不用管

GroupLayout gl_contentPane = new GroupLayout(contentPane);

gl_contentPane.setHorizontalGroup(

gl_contentPane.createParallelGroup(Alignment.LEADING)

.addComponent(panel, GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE)

);

gl_contentPane.setVerticalGroup(

gl_contentPane.createParallelGroup(Alignment.LEADING)

.addGroup(gl_contentPane.createSequentialGroup()

.addGap(25)

.addComponent(panel, GroupLayout.PREFERRED_SIZE, 264, GroupLayout.PREFERRED_SIZE)

.addContainerGap(29, Short.MAX_VALUE))

);

JButton btnExit = new JButton("Exit");

btnExit.setFocusable(false);

//添加鼠标点击事件

//当点击 Exit 按钮时退出程序

btnExit.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

System.exit(0);

}

});

JButton btnMax = new JButton("MAX");

btnMax.setFocusable(false);

btnMax.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent arg0) {

//向下还原:如果已经最大化,就还原成正常大小

if (getExtendedState()==JFrame.MAXIMIZED_BOTH) {

setExtendedState(JFrame.NORMAL);

}else {

//最大化:将JFrame设置成横向和纵向都最大化

setExtendedState(JFrame.MAXIMIZED_BOTH);

}

}

});

JButton btnMin = new JButton("MIN");

btnMin.setFocusable(false);

btnMin.addMouseListener(new MouseAdapter() {

@Override

public void mouseClicked(MouseEvent e) {

//最小化

setExtendedState(JFrame.ICONIFIED);

}

});

//下面一大段代码由系统自动生成,不用管

GroupLayout gl_panel = new GroupLayout(panel);

gl_panel.setHorizontalGroup(

gl_panel.createParallelGroup(Alignment.TRAILING)

.addGroup(gl_panel.createSequentialGroup()

.addContainerGap(217, Short.MAX_VALUE)

.addComponent(btnMin)

.addPreferredGap(ComponentPlacement.RELATED)

.addComponent(btnMax)

.addPreferredGap(ComponentPlacement.RELATED)

.addComponent(btnExit)

.addContainerGap())

);

gl_panel.setVerticalGroup(

gl_panel.createParallelGroup(Alignment.TRAILING)

.addGroup(Alignment.LEADING, gl_panel.createSequentialGroup()

.addContainerGap()

.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)

.addComponent(btnExit)

.addComponent(btnMax)

.addComponent(btnMin))

.addContainerGap(231, Short.MAX_VALUE))

);

panel.setLayout(gl_panel);

contentPane.setLayout(gl_contentPane);

}

}

MyPanel.java:

package com.siwuxie095.swing;

import java.awt.BasicStroke;

import java.awt.Color;

import java.awt.Font;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import javax.swing.JPanel;

//MyPanel 继承自 JPanel

public class MyPanel extends JPanel {

//需要复写父类 JPanel 的 paintComponent() 方法

@Override

protected void paintComponent(Graphics g) {

//使用 Java2D,创建 Graphics2D 对象,让绘制效果更好

//需要强制类型转换

Graphics2D g2d=(Graphics2D) g;

//打开抗锯齿效果

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//前三个是 rgb 值,最后一个是透明度

g2d.setColor(new Color(255,255,255,140));//白色,透明度为 140

//使用 Graphics2D 填充一个圆角矩形(作背景)

//需要指定 X Y 坐标,宽度,高度,圆角的弧宽,圆角的弧高

//宽度和高度直接调用 JPanel 的 getWidth() 和 getHeight() 方法来获取

//

//绘制边框时要注意:如果绘制的宽度和高度 与 真实边框的高度和宽度一样 ,

//那么右方和下方的边框不会显示出来(即不会显示出深灰色)

//因为绘制边框时是在指定宽度的右侧、指定高度的下侧来绘制的

//所以宽度和高度都要减 1,这样右边界和下边界才不会被绘制到界面之外

//(至于为何起始点又加 3,宽高又减 6,详见:(5)关于笔触的注释)

//

//绘制一个半透明的窗体,填充的是浅浅的白色

//(这里虽然绘制的是 contentPane,但后面的 JFrame

//已经被设为全透明,所以 contentPane 就决定了 窗体)

//g2d.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);

g2d.fillRoundRect(3, 3, getWidth()-7, getHeight()-7, 20, 20);

//绘制标题区域

//虽然 fill 的区域很大,但超出 setClip() 的部分不会被绘制

//(主要是 getHeight()-1 超出了范围)

g2d.setClip(0,0,getWidth(),30);

g2d.setColor(Color.white);

g2d.fillRoundRect(1, 3, getWidth()-2, getHeight()-1, 20, 20);

//因为 setClip() 仅针对这个标题栏有效,所以绘制完成后需要移除它,传入空值即可

g2d.setClip(null);

//(5)

//设定笔触,传入匿名对象,指定笔触宽度

//笔触宽度变大时,窗体的边角就会变的凸出

//

//这是因为在为当前的形状来绘制上边缘和左边缘时,

//每一个像素的宽度都会同时向内和同时向外扩张半个像素

//而绘制下边缘和右边缘时,每一个像素的宽度则是同时向外扩张一个像素

//

//如:当前的圆角矩形是从(0,0)开始绘制的,如果是 6 个宽度的话,

//上边缘和左边缘会向里绘制 3 个像素和向外绘制 3 个像素,

//而下边缘和右边缘则是向外绘制 6 个像素。

//所以要想完全显示该笔触(实际应用于边框,使四周宽度相同),

//绘制时需要将起始点加上宽度的一半,宽高都减去宽度

g2d.setStroke(new BasicStroke(6));

g2d.setColor(Color.darkGray);

//使用 Graphics2D 绘制一个圆角矩形(作边框)

//g2d.drawRoundRect(0, 0, getWidth()-1, getHeight()-1, 20, 20);

g2d.drawRoundRect(3, 3, getWidth()-7, getHeight()-7, 20, 20);

//绘制文字,先设定字体

g2d.setFont(new Font("Arial", Font.BOLD, 16));

g2d.drawString("Swing UI Test", 15, 24);

}

}

将 JFrame 的 undecorated 属性设为 true,即不使用系统自带的窗体装饰

将 JFrame 设为 全透明

为 JFrame 添加 keyTyped 事件,实现点击 Esc 和 Space 退出程序

为 JFrame 添加 mousePressed、mouseDragged 事件,实现窗体拖拽移动

「关于窗体拖拽移动,为 contentPane 添加同样事件也能达到同样效果」

修改 MyFrame.java(主类) 中的 contentPane 的声明与实例化方式

在 MyPanel.java 中覆盖 JPanel 类的 paintComponent() 方法,

使用 Java 2D 绘制 contentPane

在 contentPane 上添加一个新的 JPanel,将 contentPane 和这个 JPanel

的 opaque 属性设为 false,布局改为 Group Layout,并做好吸附

在新的 JPanel 的右上角添加三个 JButton,将其文本(text)分别改为:

MIN、MAX、EXIT,分别 Rename 为:btnMin、btnMax、btnExit,并

做好吸附

将三个 JButton 的 focusable 属性设为 false

为三个 JButton 添加 mouseClicked 事件,实现 最小化、最大化/向下还原、关闭

运行程序:

这是一个半透明的窗体,中间显示的是本人的桌面背景

(标题栏:Swing UI Test 所在,是白色,不是半透明)

【made by siwuixie095】

转载于:https://www.cnblogs.com/siwuxie095/p/6669047.html

使用绘图API自定义组件相关推荐

  1. 小程序高级电商前端第2周深入理解REST API开发规范 开启三端分离编程之旅<二>----scroll-view组件的灵活应用、async和await问题探讨、spu-scroll自定义组件

    前言: 转眼距离上一次写博文又过去一个月了,今年的博文节奏已经彻底被打破了: 真的是有心无力了,其原因在之前也提到过,组织架构调整,各种考核(跨领域性质的考核)实行末尾淘汰制,说不出的酸楚,不过换个心 ...

  2. 微信小程序自定义组件使用canvas绘图,无法绘制以及fail canvas is empty问题

    情况2:自定义组件引用canvas绘制,空白: 原因:查看文档,在自定义组件内需要手动传入当前实例的this,否则canvas指向的this为父组件所以无法找到正确canvas:<br / 情况 ...

  3. 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件

    博客地址 : http://blog.csdn.net/shulianghan/article/details/41520569 代码下载 : -- GitHub : https://github.c ...

  4. 自定义组件开发六 自定义组件

    概述 Android SDK 为我们提供了一套完整的组件库,数量多.功能强,涉及到方方面面,但是,我们依然看到软件市场上的每个 App 都有自己独特的东西,绝不是千遍一律的,而且也会和 IOS相互借鉴 ...

  5. 自定义组件开发五 阴影、 渐变和位图运算

    介绍阴影.渐变和位图运算等技术 阴影只是一个狭义的说法,实际上也包括发光等效果:Android 也提供了强大的渐变功能,渐变能为物体带来更真实的质感,比如可以用渐变绘制一颗五子棋或一根金属圆棒:位图运 ...

  6. 第四章 自定义组件、动画

    文章目录 第四章 自定义组件.动画 (一)View体系 (1)View简介 (2)Android坐标系 (3)视图坐标系 (二)自定义View (1)onMeasure:对当前View的尺寸进行测量 ...

  7. 微信小程序自定义组件之Picker组件

    微信小程序开发交流qq群   173683895    承接微信小程序开发.扫码加微信. 需求: 通过JS条件判断,满足条件就弹出Picker给用户选择一个数组里面的数据. 有些朋友可能会有疑问: 1 ...

  8. 微信小程序之圆形进度条(自定义组件)

    前言 昨天在微信小程序实现了圆形进度条,今天想把这个圆形进度条做成一个组件,方便以后直接拿来用. 根据官方文档自定义组件一步一步来 创建自定义组件 第一步创建项目结构 打开微信开发者工具创建一个项目, ...

  9. 【Android 内存优化】自定义组件长图组件 ( 长图滚动区域解码 | 手势识别 GestureDetector | 滑动计算类 Scroller | 代码示例 )

    文章目录 一.GestureDetector 创建与设置 二.GestureDetector 触摸事件传递 三.触摸滑动操作 四.惯性滑动操作 五.长图滑动组件代码示例 六.运行效果 七.源码及资源下 ...

最新文章

  1. 降低网站跳出率的六个方法(亲身使用)
  2. IHttpHandler的学习(0)
  3. SQL 常用数据类型汇总
  4. Vs code自动生成Doxygen格式注释
  5. Java中语法分析器_语法分析器(java语法分析器)
  6. 台积电放大招:甩开英特尔 7nm和5nm芯片将诞生
  7. 第 11 个“世界备份日”刚过,《Veeam 2021 数据保护报告》为你解读全球数据备份现状
  8. android 休眠唤醒驱动流程分析,Android4.0.4休眠唤醒机制分析(基于MSM8260)
  9. 2.1.4 Python单例模式
  10. 计算机优秀大学生,应届计算机业优秀大学生的自我鉴定
  11. 运行HelloJersey遇到异常解决方法
  12. winHex创建指定大小二进制文件.bin(数据为全0或全FF或自己填充)并带winHex软件下载包
  13. android pickerview 多行,Android PickerView实现三级联动效果
  14. InstallShield打包程序
  15. Apple Compressor 4.4.4 中文特别版 Mac 电影视频后期制作工具
  16. CCPROXY漏洞利用
  17. 分享几个关于UG装配的小问题,干货满满!!!
  18. A/B 测试:数据驱动的产品优化
  19. 用计算机怎样搜wifi网,如何用电脑设置wifi?用电脑设置wifi方法介绍
  20. html td无边框颜色,table的td设置背景颜色后边框框消失

热门文章

  1. oracle pivoting insert 用法简介
  2. 深究AngularJS——校验(非form表单)
  3. 生成pfx文件需要在服务器上执行,PEM文件和private.key文件生成IIS服务器所需的pfx文件(配置SSL用)...
  4. linux 切换python版本_linux下多个python版本切换如何设置
  5. 哲学家就餐问题linux源代码,Linux下实现哲学家就餐问题
  6. 博图编写温度程序_NTC测量温度的两个不同的数值转换程序,你会选择哪一个
  7. mysql 查看最近的语句_查看MySQL最近执行的语句
  8. 一文看懂 K8s 日志系统设计和实践
  9. fetch 自动加cookie_如何在shell中动态获取chrome浏览器的cookie信息
  10. 计算机桌面是是在哪个盘,电脑虚拟内存是设置在哪个盘的