简体   繁体   English

JButton 上的 Java ImageIcon 复制图像

[英]Java ImageIcon on JButton duplicates image

The goal of this post is to figure out why it is duplicating both images on both buttons.这篇文章的目的是弄清楚为什么它在两个按钮上都复制了两个图像。 It is VERY odd and should not be happening.这很奇怪,不应该发生。 That is the main goal.这是主要目标。 Then it would be finding a solution.然后它会找到一个解决方案。 Thank you!谢谢!

Image of what it looks like它的样子的图片

在此处输入图片说明

I've made an MRE我做了一个 MRE

It outputs both images on both buttons and I don't know why.它在两个按钮上输出两个图像,我不知道为什么。

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameManager extends JFrame{

    private final   Map <String, String> images = new HashMap<>(2);

    GameManager()
    {
        images.put("Articuno", "https://i.ya-webdesign.com/images/articuno-transparent-pokemon-xy-17.gif");
        images.put("Rayquaza", "https://play.pokemonshowdown.com/sprites/ani-back-shiny/rayquaza.gif");

        JPanel pnlPokemonInParty = new JPanel(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        //Why does it put both images on both buttons? It actually sets the images on top of one another.
        //You can tell which image is in the front and which is behind the other.
        //I'm setting the buttons to be transparent. Setting the buttons to not be transparent will cover the the image below it,
        //that's how I know they're being stacked on top of one another.
        JButton btn1 = gifBtn("Articuno");
        JButton btn2 = gifBtn("Rayquaza");
        c.gridx = 0;
        pnlPokemonInParty.add(btn1, c);
        c.gridx = 1;
        pnlPokemonInParty.add(btn2, c);
        this.add(pnlPokemonInParty);
        this.pack();
        this.setVisible(true);
    }
    public JButton gifBtn(String name)
    {
        final JButton btn = new JButton();
        URL url = null;
        try {
            url = new URL(images.get(name));
        } catch (MalformedURLException ex) {
            ex.printStackTrace();
        }
        Icon icon = new ImageIcon(url);
        btn.setIcon(icon);
        btn.setBackground(new Color(50,50,50,0));
        return btn;
    }

    public static void main(String[] args)
    {
        GameManager gameManager = new GameManager();
    }
}

I can hide the problem by not setting the background color of the Jbuttons to be transparent but that doesn't solve the problem.我可以通过将 Jbuttons 的背景颜色设置为透明来隐藏问题,但这不能解决问题。

Why does this happen?为什么会发生这种情况? I'm more so worried about the two images being on the same JButton, but there is another issue that is easily noticeable when looking at the image that I don't really know how to explain.我更担心两个图像位于同一个 JButton 上,但是在查看图像时,还有另一个问题很容易引起注意,但我真的不知道如何解释。

When posting a question it is recommended to post an MRE like the following:发布问题时,建议发布如下MRE

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameManager extends JFrame{

    private final   Map <String, String> images = new HashMap<>(2);

        GameManager()
        {
            images.put("Articuno", "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/256x256/Box_Green.png");
            images.put("Rayquaza", "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/256x256/Box_Red.png");

            JPanel pnlPokemonInParty = new JPanel(new GridBagLayout());
                GridBagConstraints c = new GridBagConstraints();
                JButton btn1 = gifBtn("Articuno");
                JButton btn2 = gifBtn("Rayquaza");
                c.gridx = 0;
                pnlPokemonInParty.add(btn1, c);
                c.gridx = 1;
                pnlPokemonInParty.add(btn2, c);
                this.add(pnlPokemonInParty);
                this.pack();
                this.setVisible(true);
        }
         public JButton gifBtn(String name)
         {
                final JButton btn = new JButton();
                URL url = null;
                try {
                    url = new URL(images.get(name));
                } catch (MalformedURLException ex) {
                    ex.printStackTrace();
                }
                Icon icon = new ImageIcon(url);
                btn.setIcon(icon);
                btn.setBackground(new Color(50,50,50,0));
                return btn;
         }

    public static void main(String[] args)
    {
            GameManager gameManager = new GameManager();
    }
 }

The code works fine using publicly available images so it suggests that there is a problem with the local resource.该代码使用公开可用的图像工作正常,因此它表明本地资源存在问题。
MRE makes helping much easier and it is a powerful debugging tool. MRE 使帮助变得更加容易,它是一个强大的调试工具。 It many case, while preparing one, you are likely to find the problem.很多情况下,在准备一个的时候,你很可能会发现问题。


Edit 1: With the newly add mre the problem is clear now: each button shows the two images one on top of the other. 编辑 1:使用新添加的 mre 问题现在很清楚:每个按钮显示两个图像一个在另一个之上。
The problem indeed disappears when removing btn.setBackground(new Color(50,50,50,0)); 删除btn.setBackground(new Color(50,50,50,0));时,问题确实消失了btn.setBackground(new Color(50,50,50,0));
This may be explained by "setBackground() doesn't read well on some platforms" taken from @trashgod answer. 这可能是由@trashgod 回答中的“setBackground() 在某些平台上读得不好”来解释的。
The problem can be eliminated by setting LAF as explained in this answer by @Andrew Thompsom. 可以通过设置 LAF 来消除该问题,如@Andrew Thompsom 在此答案中所述。
Here is an mre demonstrating it. 这是一个演示它的mre

It is up to the look and feel to honor this property, some may choose to ignore it.尊重这个属性取决于外观和感觉,有些人可能会选择忽略它。

(Quoted from JComponent#setBackground(Color) documentation .) (引自JComponent#setBackground(Color) 文档。)

Edit 2:编辑2:

A custom JButton which overrides paintComponent works properly (with transparent color where alfa is to 0 like new Color(50,50,50,0) or any other color):覆盖paintComponent自定义JButton正常工作(透明颜色,其中 alfa 为 0,如new Color(50,50,50,0)或任何其他颜色):

 class Main extends JFrame{ private final Map <String, String> images = new HashMap<>(); Main() { images.put("Articuno", "https://66.media.tumblr.com/d9105814c15295196a3dbe75c32ba1a0/tumblr_oagpklvBGf1scncwdo1_400.gif"); images.put("Rayquaza", "https://play.pokemonshowdown.com/sprites/ani-back-shiny/rayquaza.gif"); images.put("GreenCircle", "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Green.png"); images.put("RedBox", "https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/256x256/Box_Red.png"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setBackground(Color.WHITE); this.setLayout(new FlowLayout()); this.add(gifBtn("GreenCircle")); this.add(gifBtn("RedBox")); this.add(gifBtn("Articuno")); this.add(gifBtn("Rayquaza")); this.pack(); this.setVisible(true); } public JButton gifBtn(String name) { JButton btn = new CustomButton(); try { URL url = new URL(images.get(name)); btn.setIcon(new ImageIcon(url)); } catch (MalformedURLException ex) { ex.printStackTrace(); } return btn; } public static void main(String[] args) throws Exception { new Main(); } } class CustomButton extends JButton{ private final Color bgColor = new Color(255,192,203,0); public CustomButton() { //setBorderPainted(false); //optioal setContentAreaFilled(false); setOpaque(false); } @Override public void paintComponent(Graphics g){ g.setColor(bgColor); Rectangle r = g.getClipBounds(); g.fillRect(rx, ry, r.width, r.height); super.paintComponent(g); } }

JComponent#setBackground(Color) documentation states: JComponent#setBackground(Color) 文档说明:

Direct subclasses of JComponent must override paintComponent to honor this property. JComponent 的直接子类必须覆盖paintComponent 以遵守此属性。 It is up to the look and feel to honor this property, some may choose to ignore it.尊重这个属性取决于外观和感觉,有些人可能会选择忽略它。

from some reason JButton does not.由于某种原因, JButton没有。

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

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