用Java创build一个自定义的JButton

有没有办法用你自己的buttongraphics创build一个JButton ,而不仅仅是在button内部的图像?

如果没有,是否有另一种方法来在java中创build一个自定义的JButton

当我第一次学习Java时,我们必须制作Yahtzee,我认为创build自定义的Swing组件和容器,而不是仅仅绘制一个JPanel上的所有内容将会很酷。 当然,扩展Swing组件的好处是能够添加对键盘快捷键和其他辅助function的支持,而不能仅仅通过paint()一个paint()方法来打印出漂亮的图片。 然而,这可能不是最好的方式,但它可能是一个很好的起点。

编辑8/6 – 如果从图像中看不到,每个Die都是一个可以点击的button。 这将把它DiceContainer下面的DiceContainer 。 查看源代码,您可以看到每个“死亡”button都是根据其值进行dynamic绘制的。

替代文字
替代文字
替代文字

这里是基本的步骤:

  1. 创build一个扩展JComponent的类
  2. 在构造函数中调用父构造函数super()
  3. 确保你的类实现了MouseListener
  4. 把这个在构造函数中:

     enableInputMethods(true); addMouseListener(this); 
  5. 重写这些方法:

     public Dimension getPreferredSize() public Dimension getMinimumSize() public Dimension getMaximumSize() 
  6. 重写这个方法:

     public void paintComponent(Graphics g) 

绘制button时必须使用的空间量由getPreferredSize()定义,假定getMinimumSize()getMaximumSize()返回相同的值。 我还没有尝试太多,但是,根据您使用GUI的布局,您的button可能看起来完全不同。

最后, 源代码 。 万一我错过了什么。

是的,这是可能的。 使用Swing的主要优点之一是抽象控件可以轻松创build和操作。

这是一个快速和肮脏的方式来扩展现有的JButton类,以在文本的右侧绘制一个圆。

 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); } } 

请注意,通过覆盖paintComponent可以更改button的内容,但边框由paintBorder方法绘制。 还需要pipe理getPreferredSize方法以dynamic支持对内容的更改。 测量字体指标和图像尺寸时需要小心。

为了创build一个你可以依赖的控件,上面的代码不是正确的方法。 尺寸和颜色在Swing中是dynamic的,取决于所使用的外观和感觉。 即使默认的Metal外观在JRE版本中也有变化。 实现AbstractButton会更好,并符合Swing API规定的准则。 一个好的起点是查看javax.swing.LookAndFeeljavax.swing.UIManager类。

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的解剖结构对于编写控件非常有用: 创build自定义外观和感觉

你总是可以尝试合成器的外观和感觉。 您提供了一个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)方法来确定button应该在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> 

那里的绑定元素指定要映射到的内容(在这个例子中,它将把这个样式应用于名称属性已经设置为“dirt”的任何button)。

还有一些有用的链接:

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

我可能会走错一百万英里的直接(但我只是年轻的:P)。 但不能将graphics添加到面板,然后添加一个mouselistener到graphics对象,以便在graphics上的用户执行操作时。

自从我早期的CS类以来,我还没有做过SWING开发,但是如果没有构build,您可以inheritancejavax.swing.AbstractButton并创build自己的。 将某些东西与现有框架连接起来应该非常简单。