博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计3D标签
阅读量:6688 次
发布时间:2019-06-25

本文共 3755 字,大约阅读时间需要 12 分钟。

java自带的Label太枯燥了,真是拿不出手啊。

所以,我们要设计3D标签!!
看看下面这张图

原理

看看这图,可以看到哈哈有三种颜色:白色、黑色和灰色

实现的时候并不像PS那样,按几个按钮就O了
其实实际是画出3个“哈哈”,一种白色,一种黑色,一种灰色
然后想象一下,如果三种颜色的”哈哈“,重叠了起来,只留下了很小的一部分,那么就形成了阴影。
既然有三种颜色的”哈哈“,那么就需要画三次。
下面开始,我们将左上角的阴影(白色的哈哈)称为左阴影,将右下角的阴影称为由右阴影
此时阴影的位置就显得格外重要了,需要自定义左右阴影的偏移量
总所周知,对于位置的表示是坐标即横纵坐标,这时就需要设置4个偏移量——左阴影x、左阴影y、右阴影x、右阴影y
然后覆盖JLabel类中的paintComponent方法,原本这个方法只是花一次,现在我们让他画3次!!

代码实现

import java.awt.*;import javax.swing.*;public class ThreeDLabel extends JLabel{
private int tracking;//这是字符空隙 private int left_x,left_y,right_x,right_y;//四个阴影偏移量 private Color left_color,right_color;// 左右阴影的颜色 public ThreeDLabel(String text,int tracking){
//参数为文本内容和字符空隙 super(text); this.tracking=tracking; } //设置左阴影 public void setLeftShadow(int left_x,int left_y,Color left_color){ this.left_x=left_x; this.left_y=left_y; this.left_color=left_color; } //设置右阴影 public void setRightShadow(int right_x,int right_y,Color right_color){ this.right_x=right_x; this.right_y=right_y; this.right_color=right_color; } //重写getPreferredSize()方法,如果在通过setSize来设置尺寸的话,可以不覆写这个方法 public Dimension getPreferredSize(){ int x,y; FontMetrics font=this.getFontMetrics(this.getFont()); x=(getText().length()-1)*tracking+left_x+right_x+font.stringWidth(getText());//宽=字符串所有字符空隙之和+左阴影x值+右阴影x值+字符串的宽度 y=font.getHeight()+left_y+right_y; return new Dimension(x,y); } //重点!!覆写paintComponent,以达到画3次就能画出阴影效果 public void paintComponent(Graphics g){ //这句感觉是可有可无的,目的是让字体圆润柔和些,就像PS的饱和效果 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); char[] chars=getText().toCharArray(); FontMetrics fm=this.getFontMetrics(getFont()); int h=fm.getAscent(); int x=0; for(char c:chars){ int w=fm.charWidth(c)+tracking;//w=字符c的宽度+字符间隙 //画作阴影 g.setColor(left_color); g.drawString(c+"",x-left_x,h-left_y); //画右阴影 g.setColor(right_color); g.drawString(c+"",x+right_x,h+right_y); //画正文 g.setColor(getForeground()); g.drawString(c+"",x,h); x+=w; } //这句话感觉也没什么用,目的是把anti-alising状态恢复到默认值 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); }}

下面是实例代码

class Demo{    public static void main(String[] args){        DIYLabel label=new DIYLabel("小柒再出发",40);        label.setLeftShadow(2,1,Color.white);//设置左阴影属性        label.setRightShadow(4,5,Color.gray);//设置右阴影属性        label.setForeground(Color.black);//设置正文颜色        label.setFont(label.getFont().deriveFont(140f));//设置字体大小为140像素        JFrame frame=new JFrame("title");        frame.getContentPane().add(label);        frame.pack();//窗口自动调节大小        frame.setVisible(true);        }    }

结果如图

结果

几个解释的地方

为什么要有一个字符间隙tracking?

因为:当右阴影的偏移量过大时,右阴影可能就会跑到下一个字符所在的地方,这样看起来就很难看的

上图看看有字符间隙和没有字符间隙的区别
这个图的字符间隙是0,右阴影的偏移量right_x=60,right_y=40
可以看到,前一个字的右阴影和下一个字都挤到了一起了
没有字符间隙

这张图的字符间隙为80,阴影的偏移量和上一个字一样

有了字符间隙,就可以避免前一个字的阴影和下一个字挤到了一起
所以字符间隙至少是left_x+right_x
字符间隙为80

为什么要重写getPrefferedSize()?

因为pack()这个方法,可以自动调节窗口的尺寸(前提是有布局管理器,也就是不是绝对布局)

然后pack()这个方法的原理是根据每个组件的最适尺寸来安排窗体的尺寸的,也就是每个组件的getPrefferedSize()方法
现在已经知道了getPrefferedSize()的用处了,然后我们来讲讲如果不重写getPrefferedSize()会怎么样?
原始的getPrefferedSize()方法的实现是根据Label的文本信息、图标、文本信息与图标之间的距离来安排最佳尺寸的
然而原始的文本信息是没有阴影的,所以最佳尺寸也就没有加上阴影的尺寸和字符间距
这会使得,最佳尺寸偏小,甚至右边或左边的字有一部分显示不出来(超出了组件的尺寸)

画三遍的顺序有讲究

画阴影和正文的顺序有讲究,因为画画的时候,当下一次画画的时候与上一次画画有重复的部分,那么下一次画画就会覆盖上一次的部分

所以,应该先画左右阴影(左右阴影的顺序没有讲究),最后再画正文,要确保正文不被覆盖,阴影一定要被覆盖

转载于:https://www.cnblogs.com/wewill/p/5588750.html

你可能感兴趣的文章
区块链简单研读笔记
查看>>
为什么 scrum 开发人员是一个 T-形的人 ?
查看>>
使用 CODING 进行 Spring Boot 项目的集成
查看>>
web前端性能优化总结
查看>>
pandas 修改 DataFrame 列名
查看>>
《2018年云上挖矿态势分析报告》发布,非Web类应用安全风险需重点关注
查看>>
leetcode409.Longest Palindrome
查看>>
蚂蚁区块链平台BaaS技术解析与实践
查看>>
Nervos 双周报第 3 期:佛系新年之后的开工大吉!
查看>>
测试开发系类之接口自动化测试
查看>>
【PHP 扩展开发】Zephir 基础篇
查看>>
HTML
查看>>
HashMap浅析?
查看>>
字节跳动开源Go结构体标签表达式解释器,成请求参数校验的杀手锏
查看>>
怎么将在线录制的视频转为GIF动态图
查看>>
js的setTimeout和Promise---同步异步和微任务宏任务
查看>>
【剑指offer】顺时针打印矩阵
查看>>
怎么将图片上传封装成指令?
查看>>
leetcode讲解--861. Score After Flipping Matrix
查看>>
聊聊JavaScript和Scala的表达式 Expression
查看>>