详细步骤
例行说明
V1.5
已构建好MyButton
,等待V1.5.1
的调用,调用实现按钮的贴图修边美化
具体步骤
-
MyButton 构造方法初始化按钮,消去边框,设置大小
-
paintComponent()
画按钮组件 =>switchCase()
按钮分类处理 =>graphicsImageSet()
按钮贴图 & 改变形状 -
使用
MyButton
替换KeyboardPiano
中的JToggleButton
使用正则表达式 (regex) 进行替换,省时省力,详见 Option1
代码分析
- 构造函数(代码注释已经解释得够清楚了,但还是啰嗦一下)
setContentAreaFilled(false)
阻止父类(super
)画按钮setHorizontalTextPosition(SwingConstants.CENTER);
设置文字居中setBorderPainted(false);
消去按钮边框setPreferredSize(new Dimension(WIDTH, HEIGHT));
设置按钮大小,WIDTH
&HEIGHT
分别为 宽 & 高
MyButton(KeyboardPiano kp, String text, String name) {
super(text);
setOpaque(false);
/*
* the super class will paint the area of button
* if the argument is true, which is default
*/
setContentAreaFilled(false);
this.kp = kp;
this.text = text;
setImage(name);
this.setHorizontalTextPosition(SwingConstants.CENTER); //Text displays on center
this.setBorderPainted(false); //do NOT paint the border of the button
this.setPreferredSize(new Dimension(WIDTH, HEIGHT)); //the size of button(most of the case)
}
paintComponent(Graphics g)
画按钮(组件),g
理解成一支画笔- 把那支笔转换成 2D 的,升级后功能也变多了
setRenderingHint
渲染一下,具体怎么渲染,博主也不是很懂(溜)- switchCase() 根据不同的按键大小做微调,详见
switchCase()
的代码分析 - 再往下的代码的作用是根据按钮的 Pressed & Released 贴相应的图
注:这里
paintComponent()
是@Override
父类的方法,程序启动后,系统会自动调用,类似paint()
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
switchCase(g2d, imageName.charAt(TYPE_INDEX));
if(this.isSelected()) {
if(imageDown == null) { //the NO Direction case which is Brown
return;
}
g2d.drawImage(imageDown.getImage(), 1, 1, null);
} else { //default is Up
g2d.drawImage(imageUp.getImage(), 1, 1, null);
}
}
switchCase
&graphicsImageSet()
- 以 A 类型的按钮为例,
switchCase()
只是按照类型区分不同大小的按钮而已 - 重点是
graphicsImageSet()
- 参数说明:
g2d
是那支 2D 的画笔,type
为按钮类型,后面两个参数则是对圆角的大小设置 - 设置按下抬起的
ImageIcon
imageUp & imageDown(如果存在的话) - 美化的工作,交给
fillRoundRect()
处理,fill 后按钮会变成骚气的圆角矩形
拓展说明请见 Option2 具体参数的含义见 相关链接
- 参数说明:
- 以 A 类型的按钮为例,
注:
switchCase
cases 共有 6 种,分别是 A, B, C, D, E, F. 这里只通过 A 类型进行说明,细节处理请参考源码 V1.5.1 MyButton
细心的读者可能会发现潜藏的 BUG,稍微提一下,每 paint 一次,就会初始化一次按钮的贴图,重复的初始化,导致无缘无故地消耗内存,属于代码逻辑错误,以后 内存分析 的时候会详细说明
private void switchCase(Graphics2D g2d, int type) {
switch(type) {
case A :
graphicsImageSet(g2d, A_TYPE, 2, 2);
break;
}
}
private void graphicsImageSet(Graphics2D g2d, int type, int widthMinus, int heightMinus) {
imageUp.setImage(imageUp.getImage().getScaledInstance(type-widthMinus, HEIGHT-heightMinus, Image.SCALE_DEFAULT));
if(imageDown != null) {
imageDown.setImage(imageDown.getImage().getScaledInstance(type-widthMinus, HEIGHT-heightMinus, Image.SCALE_DEFAULT));
}
g2d.fillRoundRect(0, 0, type, HEIGHT, ARC_WIDTH, ARC_HEIGHT); //make Rectangle more beautiful
}
完成这些步骤后,运行程序 img1
- img1
发现部分按钮没能正确显示。。。
-
经博主排查,问题出现在配置文件 pic.properties,文件路径写错导致图片无法正确读取,改过来就行 img2 去除绿色部分(以右边为准)
-
img2
-
再次运行 img3
-
img3
这回界面漂亮多了 ^ ^
Attention
版本问题
- 上述问题在项目开发过程列入
V1.5.2
, 但由于排版原因合并到V1.5.1
底下 - 请读者注意修改好配置文件(
V1.5.2
在代码上还做了细微调整,请自行对比)
BUG
V1.3.1
版本遗留下来的 BUG 至今尚未解决,详见 BUG 记录- 按钮绑定再贴图后,BUG 更加明显,比如 Alt 键按下后其余按钮失灵,再比如 Num Lock 开启后,数字键与键盘中部按键冲突
- 后期再集中解决
Options
Option1
- regex 替换按钮(实际上是就是字符串替换)
- 匹配栏输入
JToggleButtn\(
(注意中间的反斜杠 \ ) - 替换栏输入
MyButton\(
- 按照图 img4 中的步骤按键,即可完成字符串替换
- 匹配栏输入
这里只替换对象类型而不改动引用类型,读者可以两者都改成
MyButton
,更加简单粗暴些
- img4
Option2
-
补充说明
- 学过软件工程/开发过项目的童鞋应该知道,项目正式开发前要做很多测试(准备工作)
当准备到一定程度后,会建立一个小的模型(验证可行性) - 所以博主在正式开发前的相关测试验证都是在 img5 中进行的,这也是软件工程的开发流程之一
- 学过软件工程/开发过项目的童鞋应该知道,项目正式开发前要做很多测试(准备工作)
-
img5 单个按钮