繁体   English   中英

在Java中创建自定义JButton

[英]Creating a custom JButton in Java

有没有办法用你自己的按钮图形创建一个JButton而不仅仅是按钮内的图像?

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

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

编辑8/6 - 如果图像中不明显,则每个Die都是一个可以单击的按钮。 这会将它移动到下面的DiceContainer 查看源代码,您可以看到每个Die按钮都是根据其值动态绘制的。

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

以下是基本步骤:

  1. 创建一个扩展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) 

绘制按钮时必须使用的空间量由getPreferredSize()定义,假设getMinimumSize()getMaximumSize()返回相同的值。 我没有对此进行太多实验,但根据您用于GUI的布局,您的按钮可能看起来完全不同。

最后, 源代码 如果我错过了什么。

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

这是一种快速而又脏的方法,可以扩展现有的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可以更改按钮的内容,但是边框是由paintBorder方法绘制的。 还需要管理getPreferredSize方法,以便动态支持对内容的更改。 在测量字体指标和图像尺寸时需要小心。

要创建一个可以依赖的控件,上面的代码不是正确的方法。 Swing中的尺寸和颜色是动态的,取决于所使用的外观。 甚至默认的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的解剖结构对于编写控件非常有用: 创建自定义外观

你可以随时尝试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并创建自己的。 将某些内容与现有框架连在一起应该非常简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM