java 如何创建带圆角的 JButton 扩展?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1007116/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a JButton extension with rounded corners?
提问by Boris Pavlovi?
This is a continuation of the question "Java rounded Swing JButton". I have searched for an extension of javax.swing.JButton which will inherit all runtime behavior and just override drawing of the corners.
这是“Java rounded Swing JButton”问题的延续。我已经搜索了 javax.swing.JButton 的扩展,它将继承所有运行时行为并且只是覆盖角的绘制。
Using the code given by noah.won sun forums pagethe result looks like this:
使用noah.w在sun 论坛页面上给出的代码,结果如下所示:
I'd like to be able to have the same gradient in the background, on mouse over change etc. Does anybody know how to do that?
我希望能够在背景中具有相同的渐变,鼠标悬停等变化。有谁知道如何做到这一点?
Code which creates the Java Swing window from the picture is:
从图片创建 Java Swing 窗口的代码是:
public class XrButton extends JButton implements MouseListener {
private static final long serialVersionUID = 9032198251140247116L;
String text;
boolean mouseIn = false;
public XrButton(String s) {
super(s);
text = s;
setBorderPainted(false);
addMouseListener(this);
setContentAreaFilled(false);
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
if (getModel().isPressed()) {
g.setColor(g.getColor());
g2.fillRect(3, 3, getWidth() - 6, getHeight() - 6);
}
super.paintComponent(g);
if (mouseIn)
g2.setColor(Color.red);
else
g2.setColor(new Color(128, 0, 128));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(1.2f));
g2.draw(new RoundRectangle2D.Double(1, 1, (getWidth() - 3),
(getHeight() - 3), 12, 8));
g2.setStroke(new BasicStroke(1.5f));
g2.drawLine(4, getHeight() - 3, getWidth() - 4, getHeight() - 3);
g2.dispose();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new FlowLayout());
XrButton xrButton = new XrButton("XrButton");
JButton jButton = new JButton("JButton");
frame.getContentPane().add(xrButton);
frame.getContentPane().add(jButton);
frame.setSize(150, 150);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
mouseIn = true;
}
public void mouseExited(MouseEvent e) {
mouseIn = false;
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
采纳答案by Eugene Ryzhikov
I think you've got 2 choices here:
我认为你在这里有两个选择:
1.Implement drawing yourself in a paint method of your component
1.在你的组件的paint方法中实现自己绘制
2.Create new ButtonUI for your look and feel. In this case i would suggest to use Synch LAF
2.为您的外观和感觉创建新的 ButtonUI。在这种情况下,我建议使用 Synch LAF
In both cases drawing different states is your resposibility
在这两种情况下绘制不同的状态是您的责任
回答by Russ Hayward
The best implementation I have seen of rounded buttons in Swing are in the Substance look and feel:
我在 Swing 中看到的圆形按钮的最佳实现是 Substance 的外观和感觉:
https://substance.dev.java.net/
https://substance.dev.java.net/
Not all themes have rounded buttons so you may need to change the defaults in the demo. The project is open source so it might be worth poking around in the code for some ideas.
并非所有主题都有圆形按钮,因此您可能需要更改演示中的默认设置。该项目是开源的,因此可能值得在代码中寻找一些想法。
回答by Whired
I needed to make this as well, this is what I ended up with (Metal LAF only!)
我也需要做这个,这就是我最终得到的(仅限金属 LAF!)
@Override
protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
Shape firstClip = g.getClip();
RoundRectangle2D rect = new RoundRectangle2D.Double();
double arc = Math.ceil(getSize().getHeight()/3);
rect.setRoundRect(0, 0, Math.ceil(getSize().getWidth()), Math.ceil(getSize().getHeight()), arc, arc);
Area secondClip = new Area(getBounds());
secondClip.subtract(new Area(rect));
Area finalClip = new Area(firstClip);
finalClip.subtract(secondClip);
g2.setClip(finalClip);
super.paintComponent(g2);
Color[] gradients;
if(getModel().isRollover())
{
gradients = new Color[] { new Color(184, 207, 229), new Color(122, 138, 153), new Color(184, 207, 229) };
}
else
{
gradients = new Color[] { new Color(122, 138, 153) };
}
for(int i = 0; i < gradients.length; i++)
{
arc -= 2;
g2.setColor(gradients[i]);
g2.drawRoundRect(i+1, i+1, (int)Math.ceil(getSize().getWidth()-2)-(i*2), (int)Math.ceil(getSize().getHeight()-2)-(i*2), (int)arc, (int)arc);
}
}
Which looks like this: http://i.stack.imgur.com/unZuc.png
看起来像这样:http: //i.stack.imgur.com/unZuc.png
回答by Hyman
You have to care it by yourself:
你必须自己照顾它:
- first of all you can catch every kind of action that is used on the button to change the state (like in the code, where mouseIn is used to change a color)
- then you have to care about every single paint detail you need, for example for gradients you should point to class
GradientPaintthat is used to draw gradients..
- 首先,您可以捕捉按钮上用于更改状态的各种操作(例如在代码中,mouseIn 用于更改颜色)
- 那么你必须关心你需要的每一个绘画细节,例如对于渐变,你应该指向
GradientPaint用于绘制渐变的类..
By the way mind that you have to take care of various look-and-feels and that your solution will fit just one of these..
顺便提一下,您必须注意各种外观,并且您的解决方案将只适合其中之一。


