【问题标题】:Creating a custom JButton in Java在 Java 中创建自定义 JButton
【发布时间】:2010-09-05 08:30:14
【问题描述】:

有没有办法使用您自己的按钮图形创建JButton,而不仅仅是按钮内的图像?

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

【问题讨论】:

    标签: java swing jbutton


    【解决方案1】:

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

    Edit 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 的布局,您的按钮可能看起来完全不同。

    最后是source code。以防我错过了什么。

    【讨论】:

    • 嗨,首先感谢您的代码!我建议在您的代码中添加一个“setActionComme(String Command)”。它是 Swing 中过滤事件的方法之一。 (但你可以争辩说可以添加 1001 项内容来让事情变得更好:P)
    • 要创建一个可以按下的模具,您实际上可以通过利用 setIcon/setPressedIcon 以及JButton
    【解决方案2】:

    是的,这是可能的。使用 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 的结构有助于编写控件: Creating a Custom Look and Feel

    【讨论】:

      【解决方案3】:

      您可以随时尝试 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

      【讨论】:

        【解决方案4】:

        我可能会在错误的方向行驶一百万英里(但我还很年轻:P)。但是您不能将图形添加到面板,然后将鼠标侦听器添加到图形对象,以便当用户在图形上执行您的操作时。

        【讨论】:

        • 这可行,但如果可能的话,我更喜欢使用标准的 JButton 而不是创建我的按钮类型。
        【解决方案5】:

        自从我早期的 CS 课程以来,我没有做过 SWING 开发,但如果它不是内置的,你可以继承 javax.swing.AbstractButton 并创建你自己的。将某些东西与他们现有的框架连接起来应该很简单。

        【讨论】:

          猜你喜欢
          • 2011-08-10
          • 2012-01-04
          • 1970-01-01
          • 2012-12-19
          • 1970-01-01
          • 1970-01-01
          • 2011-09-10
          • 1970-01-01
          • 2017-11-09
          相关资源
          最近更新 更多