Java:使用透明 JButton 覆盖图像

标签 java image swing jbutton

所以我正在创建一个代表自动售货机的 GUI。我只是在尝试让布局按照我想要的方式工作时遇到了一些问题。我的想法是将图像插入到 JLabel 中,然后在特定位置用透明 JButton 覆盖该图像,这样当您单击某些位置的图像时,就会触发 JButton。我还没有达到透明度,因为我目前陷入了如何使 JButton 精确到达它们需要的位置的问题。

我尝试过 setLocation 和 setBounds 但没有成功。任何有关如何在可能的自动售货机选择上准确定位 jbutton 的帮助都会很棒。

import javax.swing.*;
import javax.imageio.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;

public class vendMachine extends JFrame
{
//Frame Dimensions 
private static final int FRAME_HEIGHT = 800;
private static final int FRAME_WIDTH = 800;


private JPanel totalGUI, imagePanel, coinPanel;

public vendMachine()
{
    createComponents();
    setSize(FRAME_WIDTH, FRAME_HEIGHT);
    setTitle("Vending Machine");
}

private void createComponents()
{
    try
    {
        BufferedImage machineImg = ImageIO.read(new File("images/pepsivend.jpg"));
        JLabel machineImgLabel = new JLabel(new ImageIcon(machineImg));
        machineImgLabel.setLayout(new FlowLayout());
        JButton test = new JButton("TEST BUTTON");
        machineImgLabel.add(test);
        //test.setBounds(0,0,0,0);


        ImageIcon pennyIcon = new ImageIcon("images/coins/penny.jpg");
        JButton pennyButton = new JButton(pennyIcon);            
        ImageIcon nickelIcon = new ImageIcon("images/coins/nickel.jpg");
        JButton nickelButton = new JButton(nickelIcon);
        ImageIcon dimeIcon = new ImageIcon("images/coins/dime.jpg");
        JButton dimeButton = new JButton(dimeIcon);
        ImageIcon quarterIcon = new ImageIcon("images/coins/quarter.jpg");
        JButton quarterButton = new JButton(quarterIcon);

        coinPanel = new JPanel();
        coinPanel.setLayout(new GridLayout(4,1));
        coinPanel.add(pennyButton);
        coinPanel.add(nickelButton);
        coinPanel.add(dimeButton);
        coinPanel.add(quarterButton);


        totalGUI = new JPanel();
        totalGUI.setLayout(new BorderLayout());
        totalGUI.add(machineImgLabel, BorderLayout.CENTER);
        totalGUI.add(coinPanel, BorderLayout.EAST);
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }

    add(totalGUI);
}

}

Button needs to go here

在上图中,我需要一些有关如何获取测试按钮的帮助,以覆盖在百事可乐选择的顶部。从那里我可以使其透明并删除边框和文本。

编辑添加:所有按钮都还没有执行任何操作。在添加其他内容之前简单地尝试让布局正常运行

最佳答案

目前尚不清楚您的实际问题是什么,但是,我将从布局开始......

没有一个布局可以完成您想要的一切,有时,您需要使用多个布局并将它们组合起来。此示例使用 BorderLayoutGridBagLayout 来设置基本布局...

Example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new VendingMachinePane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class VendingMachinePane extends JPanel {

        public VendingMachinePane() {
            setLayout(new BorderLayout());
            JLabel label = new JLabel("Cover");
            // Demonstration purpose only
            label.setPreferredSize(new Dimension(200, 400));
            label.setOpaque(true);
            label.setBackground(Color.BLUE);

            add(label);

            JPanel optionsPane = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.anchor = GridBagConstraints.NORTH;

            optionsPane.setBackground(Color.DARK_GRAY);
            optionsPane.add(new JLabel("Coin Slot"), gbc);
            optionsPane.add(makeButton("Pepsi"), gbc);
            optionsPane.add(makeButton("Diet Pepsi"), gbc);
            optionsPane.add(makeButton("Slice"), gbc);
            optionsPane.add(makeButton("Dr Pepper"), gbc);
            optionsPane.add(makeButton("Lipton"), gbc);
            optionsPane.add(makeButton("Mountain Dew"), gbc);
            optionsPane.add(makeButton("Schweppes"), gbc);
            gbc.weighty = 1;
            optionsPane.add(makeButton("Pepsi"), gbc);

            add(optionsPane, BorderLayout.LINE_END);
        }

        protected JButton makeButton(String text) {
            JButton btn = new JButton(text);
            btn.setBorderPainted(false);
            btn.setContentAreaFilled(false);
            btn.setMargin(new Insets(4, 4, 4, 4));
            btn.setOpaque(false);
            return btn;
        }

    }

}

至于你的“覆盖按钮”问题,对我来说,这是没有意义的,因为 JButton 有一个 icon 属性,为什么不只使用 JButton 从哪里开始?

只需更改按钮的 borderPainted contentAreaFilledopaque 属性即可使按钮透明

// You can pass a `Icon` instead of a `String` to the constructor
JButton btn = new JButton(text);
btn.setBorderPainted(false);
btn.setContentAreaFilled(false);
btn.setMargin(new Insets(4, 4, 4, 4));
btn.setOpaque(false);

不要忘记设置一个 ActionListener ;)

已更新,根据更新的要求...

你可以...

将图像分解为多个部分,使每个元素都是自己的图像,然后使用与上面类似的方法将它们简单地应用到按钮

你可以...

在图像上映射热点,并使用 MouseListener 监视器发生 mouseClicked 事件 - 但您确实会失去键盘输入的优势

你可以...

绘制出图像的热点,并使用GridBagLayout或自定义布局管理器,将按钮映射到图像上。

关于Java:使用透明 JButton 覆盖图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46497363/

相关文章:

java - 在 Java 中加载静态编译的库

javascript - 性能方面——canvas vs base URI vs image

java - 链表/GUI toString()

java - 切换 MediaView 不起作用

java - System.out.println 到 JTextArea

java - JavaEE EJB/Web 容器中的线程创建

python - 如何暂停 for 循环并等待用户输入 matplotlib

c++ - 在图像上应用蒙版以裁剪前景会产生不完整的输出

java - Java中调用JTable.print()时是否可以设置左右边距的大小?

java - 设置外观颜色