扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
以前也看过别人的实现方式,那就是写一个JButton的子类,然后重写其paintComponent方法,再在paintComponent方法中绘制一个圆,具体思路如下:
protected void paintComponentf(Graphics g) { g.fillOval(0 ,0, getWidth(), getHeight()); ...... } ...... |
这样生成的按钮确实是一个圆形的,但当你点击这个按钮时,你会发现它仍有一个矩形框出现,这是因为只要继承了JButton,Swing就默认把它的UI设置成ButtonUI(除非你显式地设置了UI),相当于在UI里面绘制了矩形框,在paintComponent方法里面绘制了圆形背景,所以那个矩形框就一直在.
所以,要实现真正的圆形按钮,你要为其定制UI.定制的UI一般都是ComponentUI的子类,并在其paint方法中实现组件的绘制.下面是我的RoundButtonUI中实现绘制圆形的核心代码:
public void paint(Graphics g, JComponent c)
protected void paintBackground(Graphics g) //为简便起见我就用组件的背景色了,其实用的是渐变颜色的绘制,如上图 |
当然上面只是完成了圆形的绘制,实际上还要考虑边框的绘制以及鼠标按下时的绘制等,其思想基本一样,要绘制边框就把fillOval换成drawOval,要绘制鼠标按下的圆就重新设置一种颜色再fillOval.
这样只是绘制出了圆形的组件,但它其实还是方的,只不过我们没有绘制矩形边框而已,因此,只要你在组件之内,圆形区域之外点击鼠标的话,如果该组件有事件监听器,它的ActionEvent就会被触发.作为圆形按钮,我们肯定不希望它这样了,因此就要重写它的contains方法.下面是我的代码(我的按钮其实是椭圆的,只不过当长轴和短轴相等的时候就成了一个圆了,这样按钮的功能就更大了)
public boolean contains(JComponent cc, int x, int y) { float m = x * 1.0f; float n = y * 1.0f; float a = (bot_right_x - top_left_x) / 2; float b = (bot_right_y - top_left_y) / 2; float c = component.getWidth() / 2; float d = component.getHeight() / 2; return ((m - c) * (m - c)) / (a * a) + ((n - d) * (n - d)) / (b * b) <= 1; } |
实际上也就是按照椭圆内或着椭圆上任何一点带入椭圆方程中都不会大于1而算的.这样我们的组件就真正是圆形的了.
还需要解决的问题就是为按钮绘制标签,并且根据按键重新去绘制组件了,其绘制思想也都是相当的简单,我就不在再叙述!
最后再写一个继承自JComponent的类JRoundButton,然后把它的UI设置为RoundButtonUI,再为它添加上事件监听器,这样,一个真正的JRoundButton就诞生
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者