【问题标题】:Java Graphics - draw shape on JbuttonJava Graphics - 在 Jbutton 上绘制形状
【发布时间】:2015-05-05 17:02:38
【问题描述】:

我正在为 Java 中的一个类制作一个最小的绘制应用程序。我需要制作几个按钮供用户选择不同的形状,并且在这些按钮上我应该放置他们正在使用的形状的图像。例如,一个让用户画线的按钮应该有一个线的图像。一个绘制矩形的按钮,矩形应该在它上面。我需要能够在程序中执行此操作,而无需使用外部图像源。

这是我当前的按钮代码示例。

lineB = new JButton();
lineB.setBounds(0, 25, 20, 20);
lineB.setBackground(Color.WHITE);
shapePanel.add(lineB);
lineB.addActionListener(this);

【问题讨论】:

    标签: java swing jbutton paint


    【解决方案1】:
    1. 创建所需大小的 BufferedImage -- BufferedImage img = new BufferedImage(biWidth, biHeight, BufferedImage.TYPE_INT_ARGB);
    2. 通过调用 getGraphics()createGraphics()(更好,因为它为您提供 Graphics2D 对象)获取其 Graphics 上下文。
    3. 我会将此 Graphics2D 对象的 RenderingHints 设置为 all 以使用 setRenderingHints(...) 方法进行抗锯齿。这可以消除锯齿。
    4. 用这个对象画出你的形状。
    5. 释放 Graphics 对象。
    6. 使用new ImageIcon(Image image)构造函数从上面的Image创建一个ImageIcon。
    7. 使用setIcon(...) 将按钮的图标设置为上面的图标。
    8. 不要在按钮或任何东西上调用setBounds(...)

    例如,

    import java.awt.Color;
    import java.awt.Graphics2D;
    import java.awt.RenderingHints;
    import java.awt.image.BufferedImage;
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class ImageButton extends JPanel {
       private static final int IMG_WIDTH = 50;
       private static final Color SHAPE_COLOR = Color.RED;
       private static final int GAP = 4;
       private JButton circleButton = new JButton();
       private JButton squareButton = new JButton();
    
       public ImageButton() {
          BufferedImage circleImg = new BufferedImage(IMG_WIDTH, IMG_WIDTH, BufferedImage.TYPE_INT_ARGB);
          Graphics2D g2 = circleImg.createGraphics();
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g2.setColor(SHAPE_COLOR);
          int x = GAP;
          int y = x;
          int width = IMG_WIDTH - 2 * x;
          int height = IMG_WIDTH - 2 * y;
          g2.fillOval(x, y, width, height);
          g2.dispose();
          circleButton.setIcon(new ImageIcon(circleImg));
    
          BufferedImage squareImg = new BufferedImage(IMG_WIDTH, IMG_WIDTH, BufferedImage.TYPE_INT_ARGB);
          g2 = squareImg.createGraphics();
          g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
          g2.setColor(SHAPE_COLOR);
          g2.fillRect(x, y, width, height);
          g2.dispose();
          squareButton.setIcon(new ImageIcon(squareImg));
    
          add(circleButton);
          add(squareButton);
       }
    
       private static void createAndShowGui() {
          JFrame frame = new JFrame("ImageButton");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(new ImageButton());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }
    

    【讨论】:

    • 另请注意,swing 组件都具有可覆盖的绘制/更新方法,这是有意的。但是,请更喜欢 Hovercraft 的解决方案,这是 99.999% 的“正确”方法。
    • @BadZen:是的,这不好,因为你会阻止按钮的委托进行绘制。
    • 嗯,是的,你必须调用paintComponent() 来渲染委托,然后在上面涂鸦。总的来说不是很好。但也许是一些用例。只是指出来,因为它泛化到 Swing 中的各种 GUI 元素......
    【解决方案2】:

    一种简单的方法是将图像添加到 JButton 并使其成为图像按钮。

    try {
     Image icon = ImageIO.read(getClass().getResource("icons/line.jpg"));
     lineButton.setIcon(new ImageIcon(icon));
    } catch (IOException ex) {
    }
    

    已编辑:

    由于您被要求在代码中创建形状,您可以执行以下代码在内存中创建图像,绘制图像的图形,然后将其分配给按钮。

        final int BI_WIDTH = 50;
        final int BI_HEIGHT = 50;
        BufferedImage lineImage = new BufferedImage(BI_WIDTH, BI_HEIGHT,
                BufferedImage.TYPE_INT_RGB);
        lineImage.createGraphics().drawLine(2, 25, 48, 25);
        JButton lineButton = new JButton();
        lineButton.setIcon(new ImageIcon(lineImage));
    

    图形对象有许多不同的功能,你可以在上面画任何你喜欢的东西。

    【讨论】:

    • 直接违反了作业要求之一:"I need to be able to do this from within the program without using an external image source."
    • 我们在课堂上还没有经历过类似的事情,尽管我确信这会奏效,但我也知道我的教授希望我坚持我们至少已经触及的东西。他只是从未讨论过如何在按钮上执行 g.drawLine。我尝试了 lineB.set**** 的不同组合,但总是收到“此处不允许使用 void 类型”的错误
    • 另外,建议新手(或任何人)使用空的 catch 块是不安全的:catch (...) { }
    • @ChrisCampbell:我已经给你提供了你需要做什么的大纲。
    • @HovercraftFullOfEels 我不是来教如何用 Java 编码的,我只是想为这个问题提供一个简单的解决方案,人们如何处理他们的异常不在主题范围内。但是,您正确地捕获每个异常是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    相关资源
    最近更新 更多