JButton setIcon更新错误

时间:2012-06-19 05:53:45

标签: java swing netbeans jbutton imageicon

目前我正在使用netbeans制作一个基于改变按钮图像的java程序....

其实我的要求是当我点击另一个按钮(Say A)时更改按钮的图像图标.....

我出来了以下程序........

       // Following function is included inside the button's (Here A) ActionListener........
       public void change_image()
       {
             if(sex==0)
             {
                   ic=new ImageIcon("E:\\java_images\\female_profile.jpg");
                   sex=1;
             }
             else if(sex==1)
             {
                   ic = new ImageIcon("E:\\java_images\\male_profile.png");
                   sex=0;
             }

              // To resize the image into the size of the button... 
               labelicon.setImage(ic.getImage().getScaledInstance(image_btn.getWidth(),image_btn.getHeight(), Image.SCALE_DEFAULT));

             img_btn.setIcon(labelicon);

         }

我所包含的变量是

           private int sex;    // 0  - female, 1 - male

           private ImageIcon ic,labelicon;  // variables meant for storing ImageIcons.....
           private JButton img_btn;  // the button at which the image is to  be displayed....

现在我观察到的怪异行为是.......

仅当我点击最小化按钮时,图像才会显示在按钮单击上。 即,当我单击按钮A时,ActionListener中指定的代码将被执行。但是,只有当我最小化窗口并再次使其出现在屏幕上时才会出现图像更改的效果 ....任何人都可以告诉为什么会发生这种情况,我该如何解决问题?

我想要的只是在点击A按钮时改变图像..... 嗯...我没有包含创建按钮的代码,因为它们很容易通过netbeans swing GUI builder ......

完成

3 个答案:

答案 0 :(得分:3)

  1. 一次加载Icon / ImageIcon作为本地变量,没有理由从ActionListener重新加载图片

  2. API中的
  3. 描述Image#ScaledInstance非常异步

  4. 否则你必须致电

  5. labelicon.getImage().flush();
    img_btn.setIcon(labelicon);
    

    修改

    @akp写道但是..你会如何调整图标图像的大小.. ??

    enter image description here enter image description here enter image description here

    有两种或三种方法如何放置Icon / ImageIcon并且可以通过其父级进行解析,JLabel可以是最简单的方法

    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.util.Random;
    import javax.swing.*;
    
    public class JButtonAndIcon {
    
        private static JLabel label = new JLabel();
        private static Random random = new Random();
        private static ImageIcon image1; // returns null don't worry about 
        private static ImageIcon image2; // returns null don't worry about 
        private static Timer backTtimer;
        private static int HEIGHT = 300, WEIGHT = 200;
    
        public static void main(String[] args) throws IOException {
            label.setPreferredSize(new Dimension(HEIGHT, WEIGHT));
            final JButton button = new JButton("Push");
            button.setBorderPainted(false);
            button.setBorder(null);
            button.setFocusable(false);
            button.setMargin(new Insets(0, 0, 0, 0));
            button.setContentAreaFilled(false);
            button.setLayout(new BorderLayout());
            button.add(label);
            button.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (button.getIcon() == image1) {
                        label.setIcon(image2);
                    } else {
                        label.setIcon(image1);
                    }
                }
            });
            JFrame frame = new JFrame("Test");
            frame.add(button);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            startBackground();
            frame.setVisible(true);
        }
    
        private static void startBackground() {
            backTtimer = new javax.swing.Timer(750, updateBackground());
            backTtimer.start();
            backTtimer.setRepeats(true);
        }
    
        private static Action updateBackground() {
            return new AbstractAction("Background action") {
    
                private static final long serialVersionUID = 1L;
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setIcon(new ImageIcon(getImage()));
                }
            };
        }
    
        public static BufferedImage getImage() {
            int w = label.getWidth();
            int h = label.getHeight();
            GradientPaint gp = new GradientPaint(0f, 0f, new Color(
                    127 + random.nextInt(128),
                    127 + random.nextInt(128),
                    127 + random.nextInt(128)),
                    w, w,
                    new Color(random.nextInt(128), random.nextInt(128), random.nextInt(128)));
            BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = bi.createGraphics();
            g2d.setPaint(gp);
            g2d.fillRect(0, 0, w, h);
            g2d.setColor(Color.BLACK);
            return bi;
        }
    }
    

答案 1 :(得分:3)

这里的问题是您正在更新Icon的内部。 setIcon方法会认为它与按钮已有的图标相同。我建议你使用两个不同的Icon个对象来用来更新图标。这将解决问题。


示例(带有两个不同的图标):

public static void main(String[] args) throws IOException {

    final ImageIcon redIcon = createImageIcon(10, 10, Color.RED);
    final ImageIcon blueIcon = createImageIcon(10, 10, Color.BLUE);

    final JButton button = new JButton("Push", blueIcon);
    button.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if (button.getIcon() == redIcon)
                button.setIcon(blueIcon);
            else
                button.setIcon(redIcon);
        }
    });

    JFrame frame = new JFrame("Test");
    frame.add(button);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}

private static ImageIcon createImageIcon(int w, int h, Color color) {
    Image image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
    Graphics g = image.getGraphics(); 
    g.setColor(color); 
    g.fillRect(0, 0, w, h); 
    g.dispose();
    return new ImageIcon(image);
}

背景:

查看AbstractButton.setIcon的来源,您可以看到,如果引用“未更新”,它将无法了解更新:

    .....
    if (defaultIcon != oldValue) {
        if (defaultIcon == null || oldValue == null ||
            defaultIcon.getIconWidth() != oldValue.getIconWidth() ||
            defaultIcon.getIconHeight() != oldValue.getIconHeight()) {
            revalidate();
        } 
        repaint();
    }

注意@HarryJoy,即使你不知道为什么......你真的有一点...... :)对不起!再次+1!

答案 2 :(得分:1)

//致电img_btn.revalidate()img_btn.repaint()

更正,setIcon应该已经这样做了。我亲自使用img_btn.setText("<HTML><BODY><IMG SRC=\"/path/to/img.jpg\"/></BODY</HTML>");的hacky方式。