KeyboardPianoV1.5.1 MyButton(调用)


详细步骤

例行说明

  • V1.5 已构建好 MyButton,等待 V1.5.1 的调用,调用实现按钮的贴图修边美化

具体步骤

  • MyButton 构造方法初始化按钮,消去边框,设置大小

  • paintComponent() 画按钮组件 => switchCase() 按钮分类处理 => graphicsImageSet() 按钮贴图 & 改变形状

  • 使用 MyButton 替换 KeyboardPiano 中的 JToggleButton 使用正则表达式 (regex) 进行替换,省时省力,详见 Option1

代码分析

  • 构造函数(代码注释已经解释得够清楚了,但还是啰嗦一下)
    1. setContentAreaFilled(false) 阻止父类(super)画按钮
    2. setHorizontalTextPosition(SwingConstants.CENTER); 设置文字居中
    3. setBorderPainted(false); 消去按钮边框
    4. 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 理解成一支画笔
    1. 把那支笔转换成 2D 的,升级后功能也变多了
    2. setRenderingHint 渲染一下,具体怎么渲染,博主也不是很懂(溜)
    3. switchCase() 根据不同的按键大小做微调,详见 switchCase() 的代码分析
    4. 再往下的代码的作用是根据按钮的 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()
    1. A 类型的按钮为例,switchCase() 只是按照类型区分不同大小的按钮而已
    2. 重点是 graphicsImageSet()
      1. 参数说明:g2d 是那支 2D 的画笔type按钮类型,后面两个参数则是对圆角的大小设置
      2. 设置按下抬起的 ImageIcon imageUp & imageDown(如果存在的话)
      3. 美化的工作,交给 fillRoundRect() 处理,fill 后按钮会变成骚气的 圆角矩形
        拓展说明请见 Option2 具体参数的含义见 相关链接

注: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
    img1

发现部分按钮没能正确显示。。。

  • 经博主排查,问题出现在配置文件 pic.properties文件路径写错导致图片无法正确读取,改过来就行 img2 去除绿色部分(以右边为准)

  • img2
    img2

  • 再次运行 img3

  • 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 替换按钮(实际上是就是字符串替换)
    1. 匹配栏输入 JToggleButtn\( (注意中间的反斜杠 \ )
    2. 替换栏输入 MyButton\(
    3. 按照图 img4 中的步骤按键,即可完成字符串替换

这里只替换对象类型而不改动引用类型,读者可以两者都改成 MyButton,更加简单粗暴些

  • img4
    img4

Option2

  • 补充说明

    1. 学过软件工程/开发过项目的童鞋应该知道,项目正式开发前要做很多测试(准备工作)
      当准备到一定程度后,会建立一个小的模型(验证可行性)
    2. 所以博主在正式开发前的相关测试验证都是在 img5 中进行的,这也是软件工程的开发流程之一
  • img5 单个按钮
    img5


相关链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值