有没有办法创建一个带有自己按钮图形的JButton
,而不仅仅是在按钮内部插入图像?
如果没有,那么在Java中是否有其他创建自定义JButton
的方法?
当我刚学习Java时,我们要制作Yahtzee游戏,并且我认为创建自定义的Swing组件和容器比仅在一个JPanel上绘制所有内容更加酷炫。当然,扩展Swing组件的好处是可以添加支持键盘快捷键和其他辅助功能,这些功能仅通过paint()方法打印漂亮的图片是无法实现的。然而,可能不是最好的方式,但它可以成为您的一个很好的起点。
Edit 8/6 - 如果从图像中看不出来,每个Die都是一个可以单击的按钮。这将把它移动到下面的DiceContainer中。从源代码中可以看到,每个Die按钮是动态绘制的,基于其值。
以下是基本步骤:
super()
MouseListener
把这段代码放在构造函数里:
enableInputMethods(true);
addMouseListener(this);
重写这些方法:
public Dimension getPreferredSize()
public Dimension getMinimumSize()
public Dimension getMaximumSize()
重写这个方法:
public void paintComponent(Graphics g)
getPreferredSize()
定义,假设getMinimumSize()
和getMaximumSize()
返回相同的值。根据您在GUI中使用的布局方式,您的按钮可能看起来完全不同。package test;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
public class MyButton extends JButton {
private static final long serialVersionUID = 1L;
private Color circleColor = Color.BLACK;
public MyButton(String label) {
super(label);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension originalSize = super.getPreferredSize();
int gap = (int) (originalSize.height * 0.2);
int x = originalSize.width + gap;
int y = gap;
int diameter = originalSize.height - (gap * 2);
g.setColor(circleColor);
g.fillOval(x, y, diameter, diameter);
}
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
size.width += size.height;
return size;
}
/*Test the button*/
public static void main(String[] args) {
MyButton button = new MyButton("Hello, World!");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
Container contentPane = frame.getContentPane();
contentPane.setLayout(new FlowLayout());
contentPane.add(button);
frame.setVisible(true);
}
}
http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html
http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html
了解LookAndFeel的结构对于编写控件非常有用: 创建自定义的LookAndFeel
您可以尝试使用Synth外观。您提供一个作为样式表的xml文件,以及您想要使用的任何图像。代码可能如下所示:
try {
SynthLookAndFeel synth = new SynthLookAndFeel();
Class aClass = MainFrame.class;
InputStream stream = aClass.getResourceAsStream("\\default.xml");
if (stream == null) {
System.err.println("Missing configuration file");
System.exit(-1);
}
synth.load(stream, aClass);
UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
System.err.println("Bad configuration file");
pe.printStackTrace();
System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
System.err.println("Old JRE in use. Get a new one");
System.exit(-3);
}
接下来,按照正常步骤添加JButton。唯一的变化是你需要使用setName(string)方法来标识按钮在xml文件中应该映射到哪里。
XML文件可能如下所示:
<synth>
<style id="button">
<font name="DIALOG" size="12" style="BOLD"/>
<state value="MOUSE_OVER">
<imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
<insets top="2" botton="2" right="2" left="2"/>
</state>
<state value="ENABLED">
<imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
<insets top="2" botton="2" right="2" left="2"/>
</state>
</style>
<bind style="button" type="name" key="dirt"/>
</synth>
bind元素指定要映射的内容(在此示例中,它将应用该样式到任何name属性设置为"dirt"的按钮)。
还有几个有用的链接:
http://javadesktop.org/articles/synth/
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html
我可能正在错误的方向上走得飞快(但我还很年轻:P)。但是你不能把图形添加到面板中,然后将鼠标侦听器添加到图形对象中,这样当用户在图形上时就会执行你的操作。
我自从上CS课程以来就没有进行过SWING开发,但如果没有内置的话,你可以继承javax.swing.AbstractButton
并创建自己的按钮。使用现有的框架应该很容易地将一些东西连接在一起。