用Java创建一个自定义的JButton

bsit 发布于 2018-02-09 java 最后更新 2018-02-09 01:07 970 浏览

有没有办法用你自己的按钮图形创建一个JButton,而不仅仅是在按钮内部的图像? 如果没有,是否有另一种方法来在java中创建自定义的JButton

已邀请:

aet

赞同来自:

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

laut

赞同来自:

你总是可以尝试合成器的外观&感觉。您提供了一个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>
那里的绑定元素指定要映射到的内容(在这个例子中,它将把这个样式应用于其名称属性已经设置为“dirt”的任何按钮)。 还有一些有用的链接: http://javadesktop.org/articles/synth/ http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

fnam

赞同来自:

是的,这是可能的。使用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中是动态的,取决于所使用的外观和感觉。甚至在JRE版本中,默认的 Metal 外观也已更改。实现 AbstractButton 会更好,并符合Swing API规定的准则。一个好的起点是查看 javax.swing.LookAndFeel javax.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的解剖对编写控件很有用: Creating a Custom Look and Feel

inemo

赞同来自:

当我第一次学习Java时,我们必须制作Yahtzee,而且我认为创建自定义的Swing组件和容器将会很酷,而不是仅仅在JPanel上绘制所有的东西。当然,扩展Swing组件的好处是能够添加对键盘快捷键和其他辅助功能的支持,而这只能通过paint()方法才能打印出漂亮的图片。然而,这可能不是最好的方式,但它可能是一个很好的起点。 编辑8/6 - 如果从图像中看不到,每个Die都是一个可以点击的按钮。这将把它移到下面的DiceContainer。查看源代码,您可以看到每个“死亡”按钮都是根据其值进行动态绘制的。

alt text结果 alt text结果 alt text 这里是基本的步骤:
  1. 创建一个扩展JComponent
  2. 的类
  3. 在构造函数中调用父构造函数super()
  4. 确保你的类实现了MouseListener
  5. 把这个放在构造函数中:
    enableInputMethods(true);   
    addMouseListener(this);
    
  6. 重写这些方法:
    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  7. 重写这个方法:
    public void paintComponent(Graphics g)
    
getPreferredSize()定义绘制按钮时必须处理的空间量,假定getMinimumSize()getMaximumSize()返回相同的值。我还没有尝试太多,但是,根据您使用GUI的布局,您的按钮可能看起来完全不同。 最后是source code。万一我错过了什么。

taut

赞同来自:

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