为组件设定UI

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

工程名:CustomizeSwing

包名:com.siwuxie095.swing

类名:MyFrame.java(主类)、MyPanel.java、MyButtonUI.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 就完全透明了

//(透明度为 0,前三个 rgb 值实际不起作用)

//因为 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");

//为 EXIT 关闭按钮指定UI

btnExit.setUI(new MyButtonUI());

btnExit.setFocusable(false);

//添加鼠标点击事件

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

btnExit.addMouseListener(new MouseAdapter() {

@Override

public
void mouseClicked(MouseEvent e) {

System.exit(0);

}

});

JButton btnMax = new JButton("MAX");

//为 MAX 最大化/向下还原按钮指定UI

btnMax.setUI(new MyButtonUI());

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");

//为 MIN 最小化按钮指定UI

btnMin.setUI(new MyButtonUI());

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);

}

}

MyButtonUI.java:


package com.siwuxie095.swing;

import java.awt.Color;

import java.awt.FontMetrics;

import java.awt.Graphics;

import java.awt.Rectangle;

import javax.swing.AbstractButton;

import javax.swing.ButtonModel;

import javax.swing.JComponent;

import javax.swing.LookAndFeel;

import javax.swing.plaf.basic.BasicButtonUI;

import sun.swing.SwingUtilities2;

/**

* 定制 ButtonUI,修改样式

* 法一:创建 MyButtonUI,继承自 BasicButtonUI,对按钮进行 setUI()

* 法二:创建 MyButton,继承自 JButton,同时覆盖 paintComponent()方法(就像 MyPanel 一样)

*

* 这两种方式都可以,且比较灵活,任意选用即可

*/

//MyButtonUI 继承自 BasicButtonUI

public class MyButtonUI extends BasicButtonUI {

//覆盖 BasicButtonUI 的一些方法,

//右键->Source->Override/Implement Methods->BasicButtonUI

@Override

protected
void installDefaults(AbstractButton b) {

super.installDefaults(b);

//将 opaque 属性设为 false

//(这是从父类中复制粘贴过来的)

LookAndFeel.installProperty(b, "opaque", Boolean.FALSE);

}

//绘制要有顺序,不然可能会覆盖之前绘制的元素

@Override

public
void paint(Graphics g, JComponent c) {

//设置按钮背景颜色为半透明红色

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

g.setColor(new Color(255,0,0,150));

//填充圆角矩形的按钮背景

g.fillRoundRect(0, 0, c.getWidth(), c.getHeight(), 10, 10);

super.paint(g, c);

}

//绘制按钮中显示的文本,可以将父类中的代码复制粘贴过来,进行修改

@Override

protected
void paintText(Graphics g, JComponent c, Rectangle textRect, String text) {

AbstractButton b = (AbstractButton) c;

ButtonModel model = b.getModel();

FontMetrics fm = SwingUtilities2.getFontMetrics(c, g);

int mnemonicIndex = b.getDisplayedMnemonicIndex();

/* Draw the Text */

if(model.isEnabled()) {

/*** paint the text normally */

//按照平常的方式绘制按钮文本

//g.setColor(b.getForeground());

g.setColor(Color.WHITE);//将文本绘制成白色

SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,

textRect.x + getTextShiftOffset(),

textRect.y + fm.getAscent() + getTextShiftOffset());

}

else {

/*** paint the text disabled ***/

//当前按钮被禁用后,文本如何绘制

g.setColor(b.getBackground().brighter());

SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,

textRect.x, textRect.y + fm.getAscent());

g.setColor(b.getBackground().darker());

SwingUtilities2.drawStringUnderlineCharAt(c, g,text, mnemonicIndex,

textRect.x - 1, textRect.y + fm.getAscent() - 1);

}

}

@Override

protected
void paintButtonPressed(Graphics g, AbstractButton b) {

//当按钮按下时,背景颜色发生变化:变成半透明蓝色

g.setColor(new Color(0,0,255,150));

g.fillRoundRect(0, 0, b.getWidth(), b.getHeight(), 10, 10);

super.paintButtonPressed(g, b);

}

}


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,并分别指定 UI:setUI(new MyButtonUI())

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


MyButtonUI.java 中覆盖 BasicButtonUI 类的一些方法

右键->Source->Override/Implement Methods->BasicButtonUI

运行程序:

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

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

按钮也是半透明的红色,按下按钮时变成半透明的蓝色

【made by siwuxie095】

时间: 2024-08-02 10:20:47

为组件设定UI的相关文章

Unity3D拖尾组件在Ui界面下正常显示

在项目中Canvas下UI添加拖尾效果,会发现Ui完全遮挡住了拖尾. 如果要正常显示通常需要对Canvas进行设置,Render Mode 我这里用的是-Camera模式 其次要对Material 下的Render Queue 进行设定,默认3000 这里需要设定为3000以下 最后就是对Trail Renderer组件进行如下设定 至此,拖尾效果正常显示在游戏界面!

Android组件及UI框架大全

Android 是目前最流行的移动操作系统(还需要加之一吗?). 随着新版本的不断发布, Android的功能也日益强大, 涌现了很多流行的应用程序, 也催生了一大批的优秀的组件. 本文试图将目前流行的组件收集起来以供参考, 如果你发现本文还没有列出的组件,欢迎在评论中贴出来,我会定期的更新本文. 很好的中文教程 Google Android官方培训课程中文版 awesome-android, android列表. 另,github上的一个项目, 收集了好多的Android开源项目. andro

微信小程序组件构建UI界面小练手 —— 表单登录注册微信小程序

通过微信小程序中丰富的表单组件来完成登录界面.手机快速注册界面.企业用户注册界面的微信小程序设计. 将会用到view视图容器组件.button按钮组件.image图片组件.input输入框组件.checkbox多项选择器组件.switch开关选择组件.navigator页面连接组件等. Ⅰ.登录设计 登录表单中,需输入账号.密码进行登录,在账号.密码输入框中都有友好的提示信息:登录按钮默认是灰色不可用状态,只有输入内容后,才会变为可用状态:在登录按钮下面提供手机快速注册.企业用户注册.找回密码链

推荐使用Tiny Framework web开发UI组件

TINY FRAMEWORK 基于组件化的J2EE开发框架,from:http://www.tinygroup.org/ 名字 Tiny名称的来历 取名Tiny是取其微不足道,微小之意. Tiny的构建者认为,一个J2EE开发框架是非常复杂的,只有把框架分解成非常细小.可控的部分,并且对每个细小.可控的部分都有一个最优解或相对最优解, 那么整个方案也就可以非常不错的落地. 策略 Tiny框架的构建策略 Think big, start small, scale fast. 想法要宏伟,但是要从小

利用 jQuery UI 和 Ajax 创建可定制的 Web 界面

如今,网站比以往更具可定制性,允许用户更改其空间,根据自己的喜好对其进行个性化.个性化的主页或仪表板页面(例如 iGoogle.MyYahoo! 和 MyAOL)日渐普及,大多数 Web 应用程序内甚至也整合了类似的功能.jQuery 库简化了此类复杂 JavaScript 交互的编写,随着 jQuery UI 的引入,这项功能得到了进一步的简化,该库以易于访问的 jQuery 插件的形式提供了常用用户界面类型. 本文介绍了如何利用 Ajax 和 jQuery UI 创建具有各种定制功能的高度可

vue组件最佳实践

看了老外的一篇关于组件开发的建议(强烈建议阅读英文原版),感觉不错翻译一下加深理解. 这篇文章制定一个统一的规则来开发你的vue程序,以至于达到一下目的.1.让开发者和开发团队更容易发现一些事情.2.让你更好的利用你的IDE.3.让你更加容易的使用打包工具4.让你的代码更容易碎片化以达到复用的目的. 基于模块开发 用一些功能单一的小模块来组织你的应用 Why? 对于你自己和你团队的人来说较小的模块更容易看懂 维护 复用和调试. How? 每个组件应该保持单一 独立 可复用 可测试把你很大的组件拆

基于jquery开发的UI框架整理分析

根据调查得知,现在市场中的UI框架差不多40个左右,不知大家都习惯性的用哪个框架,现在市场中有几款UI框架稍微的成熟一些,也是大家比较喜欢的一种UI框架,那应该是jQuery,有部分UI框架都是根据jQuery研发出来的产品,现在也很常见了. 国产jQuery UI框架 (jUI) DWZ DWZ富客户端框架(jQuery RIA framework), 是中国人自己开发的基于jQuery实现的Ajax RIA开源框架.设计目标是简单实用,快速开发,降低ajax开发成本. jQuery 部件布局

客户端高性能组件化框架React简介、特点、环境搭建及常用语法

明天就是春节了 预祝大家新春快乐 [ ]~( ̄▽ ̄)~* 天天饭局搞得我是身心疲惫= = 所以更新比较慢 今天想跟大家分享的就是这个大名鼎鼎的React框架 简介 React是这两年非常流行的框架 并不难,还是挺容易上手的 起源于Facebook内部项目(一个广告系统) 传统页面从服务器获取数据,显示到浏览器上,用户输入数据传入服务器 但随着数据量增大,越来越难以维护了 Facebook觉得MVC不能满足他们的扩展需求了(巨大的代码库和庞大的组织) 每当需要添加一项新的功能或特性时,系统复杂度就

后台管理UI

后台管理UI 目录 一.EasyUI 二.DWZ JUI 三.HUI 四.BUI 五.Ace Admin 六.Metronic 七.H+ UI 八.Admin LTE 九.INSPINIA 十.LigerUI 十一.其它UI 十二.总结 最近要做一个企业的OA系统,以前一直使用EasyUI,一切都好,但感觉有点土了,想换成现在流行的Bootstrap为基础的后台UI风格,想满足的条件应该达到如下几个: 1.美观.大方.简洁 2.兼容IE8.不考虑兼容IE6/IE7,因为现在还有很多公司在使用Wi