在选择JMenuItem时更改JPanel中的图像。

huangapple go评论83阅读模式
英文:

Change image in a JPanel when JMenuItem is chosen

问题

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

class Tests {
    JMenu w, Rail, Cann, Miss;
    JMenuItem r1, r3, r5, r7, r9, c1, c3, c5, c7, c9, m1, m3, m5, m7, m9;
    private static BufferedImage h_empty, t1, t2, placeholder;
    private boolean br1 = false, br3 = false, br5 = false, br7 = false, br9 = false, bc1 = false, bc3 = false, bc5 = false, bc7 = false, bc9 = false,
            bm1 = false, bm3 = false, bm5 = false, bm7 = false, bm9 = false;
    JFrame f = new JFrame("EveSim");
    JPanel panel = new JPanel();

    Tests() {
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 48, 48);
        panel.setBackground(Color.black);
        try {
            h_empty = ImageIO.read(new File("Icon_fit_high.png"));
        } catch (IOException ex) {
            System.out.println("Error: Image Failed to Load!");
        }
        try {
            t1 = ImageIO.read(new File("index.png"));
        } catch (IOException ex) {
            System.out.println("Error: Image Failed to Load!");
        }
        try {
            t2 = ImageIO.read(new File("index1.png"));
        } catch (IOException ex) {
            System.out.println("Error: Image Failed to Load!");
        }
        placeholder = h_empty;
        ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
        JLabel jl = new JLabel(imageIcon);
        panel.add(jl);
        JMenuBar mb = new JMenuBar();
        w = new JMenu("High Slot");
        Rail = new JMenu("Railguns");
        Cann = new JMenu("Cannons");
        Miss = new JMenu("Missiles");
        r1 = new JMenuItem("Tech 1");
        r1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                Reset();
                br1 = !br1;
                System.out.println("rail-tech1");
                placeholder = t1;
                p_add();
            }
        });
        r3 = new JMenuItem("Tech 3");
        r3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ev) {
                Reset();
                br3 = !br3;
                System.out.println("rail-tech3");
                placeholder = t2;
                p_add();
            }
        });
        r5 = new JMenuItem("Tech 5");
        r7 = new JMenuItem("Tech 7");
        r9 = new JMenuItem("Tech 8");
        c1 = new JMenuItem("Tech 1");
        c3 = new JMenuItem("Tech 3");
        c5 = new JMenuItem("Tech 5");
        c7 = new JMenuItem("Tech 7");
        c9 = new JMenuItem("Tech 8");
        m1 = new JMenuItem("Tech 1");
        m3 = new JMenuItem("Tech 3");
        m5 = new JMenuItem("Tech 5");
        m7 = new JMenuItem("Tech 7");
        m9 = new JMenuItem("Tech 8");

        Rail.add(r1);
        Rail.add(r3);
        Rail.add(r5);
        Rail.add(r7);
        Rail.add(r9);
        Cann.add(c1);
        Cann.add(c3);
        Cann.add(c5);
        Cann.add(c7);
        Cann.add(c9);
        Miss.add(m1);
        Miss.add(m3);
        Miss.add(m5);
        Miss.add(m7);
        Miss.add(m9);
        w.add(Rail);
        w.add(Cann);
        w.add(Miss);
        mb.add(w);
        f.setJMenuBar(mb);
        f.add(panel);
        f.setSize(400, 400);
        f.setLayout(null);
        f.setVisible(true);
    }

    private Image fitimage(Image img, int w, int h) {
        BufferedImage resizedimage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = resizedimage.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2.drawImage(img, 0, 0, w, h, null);
        g2.dispose();
        return resizedimage;
    }

    private void p_add() {
        panel.setBounds(0, 0, 48, 48);
        panel.setBackground(Color.black);
        ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
        JLabel jl = new JLabel(imageIcon);
        panel.add(jl);
        f.add(panel);
    }

    private void Reset() {
        br1 = false;
        br3 = false;
        br5 = false;
        br7 = false;
        br9 = false;
        bc1 = false;
        bc3 = false;
        bc5 = false;
        bc7 = false;
        bc9 = false;
        bm1 = false;
        bm3 = false;
        bm5 = false;
        bm7 = false;
        bm9 = false;
    }

    public static void main(String args[]) {
        new Tests();
    }
}
英文:

I am having trouble with JMenu and I suspect it's bacause I've misunderstood how Jframe works in regards to live updating. Apologies in advance for the sloppily put together code as its my testing grounds for ideas.

currently this code produces a JFrame with a JMenu named High Slot, with 3 sub menus, each with 5 option. only the first 2 options of the rail sub menu have an action listener for now. Under it I have a JPanel with an image that auto scales to the JPanels size.

The issue is that when I click one of the options, it doesnt update the picture like I think it should. And I know the Action listener is working because I make it print out a statement whenever it fires.

What am I doing wrong?

import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.imageio.*;
class Tests {
JMenu w, Rail, Cann, Miss;
JMenuItem r1,r3,r5,r7,r9,c1,c3,c5,c7,c9,m1,m3,m5,m7,m9;
private static BufferedImage h_empty, t1, t2, placeholder;
private boolean br1 = false, br3 = false, br5 = false, br7 = false, br9 = false, bc1 = false, bc3 = false, bc5 = false, bc7 = false, bc9 = false, 
bm1 = false, bm3 = false, bm5 = false, bm7 = false, bm9 = false;
JFrame f= new JFrame("EveSim");
JPanel panel=new JPanel();
Tests(){
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
JPanel panel=new JPanel();  
panel.setBounds(0,0,48,48);    
panel.setBackground(Color.black);
try { 
h_empty = ImageIO.read(new File("Icon_fit_high.png"));
} catch(IOException ex) {
System.out.println("Error: Image Failed to Load!");
}
try { 
t1 = ImageIO.read(new File("index.png"));
} catch(IOException ex) {
System.out.println("Error: Image Failed to Load!");
}
try { 
t2 = ImageIO.read(new File("index1.png"));
} catch(IOException ex) {
System.out.println("Error: Image Failed to Load!");
}
placeholder = h_empty;
ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
JLabel jl = new JLabel(imageIcon);
panel.add(jl);
JMenuBar mb=new JMenuBar();  
w=new JMenu("High Slot");  
Rail=new JMenu("Railguns");  
Cann=new JMenu("Cannons");
Miss=new JMenu("Missiles");
r1=new JMenuItem("Tech 1");
r1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
Reset();
br1 = !br1;
System.out.println("rail-tech1");
placeholder = t1;
p_add();
}
});
r3=new JMenuItem("Tech 3");
r3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
Reset();
br3 = !br3;
System.out.println("rail-tech3");
placeholder =t2;
p_add();
}
});  
r5=new JMenuItem("Tech 5");  
r7=new JMenuItem("Tech 7");  
r9=new JMenuItem("Tech 8");
c1=new JMenuItem("Tech 1");  
c3=new JMenuItem("Tech 3");  
c5=new JMenuItem("Tech 5");  
c7=new JMenuItem("Tech 7");  
c9=new JMenuItem("Tech 8");
m1=new JMenuItem("Tech 1");  
m3=new JMenuItem("Tech 3");  
m5=new JMenuItem("Tech 5");  
m7=new JMenuItem("Tech 7");  
m9=new JMenuItem("Tech 8"); 
Rail.add(r1); Rail.add(r3); Rail.add(r5); Rail.add(r7); Rail.add(r9); 
Cann.add(c1); Cann.add(c3); Cann.add(c5); Cann.add(c7); Cann.add(c9); 
Miss.add(m1); Miss.add(m3); Miss.add(m5); Miss.add(m7); Miss.add(m9); 
w.add(Rail); w.add(Cann); w.add(Miss);
mb.add(w);  
f.setJMenuBar(mb);  
f.add(panel);
f.setSize(400,400);  
f.setLayout(null);  
f.setVisible(true);
}
private Image fitimage(Image img , int w , int h) {
BufferedImage resizedimage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedimage.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(img, 0, 0,w,h,null);
g2.dispose();
return resizedimage;
}
private void p_add() {
panel.setBounds(0,0,48,48);    
panel.setBackground(Color.black);
ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
JLabel jl = new JLabel(imageIcon);
panel.add(jl);
f.add(panel);
}
private void Reset() {
br1 = false;
br3 = false;
br5 = false; 
br7 = false; 
br9 = false; 
bc1 = false; 
bc3 = false; 
bc5 = false; 
bc7 = false; 
bc9 = false; 
bm1 = false; 
bm3 = false; 
bm5 = false; 
bm7 = false;
bm9 = false;
}
public static void main(String args[]){
new Tests();
}
}

答案1

得分: 1

private void p_add() {
   panel.setBounds(0, 0, 48, 48);
   panel.setBackground(Color.black);
   ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
   JLabel jl = new JLabel(imageIcon);
   panel.add(jl);
   f.add(panel);
}

问题在于您不断向框架中添加组件,由于 Swing 绘制逻辑的原因,您看不到新添加的组件。

  1. 不要使用 setBounds() 方法。Swing 设计时考虑了与布局管理器一起使用。
  2. 不要不断创建新组件。您应该在类的构造函数中创建并添加 JLabel 到框架中。然后在 ActionListener 中,您只需创建一个新的 ImageIcon,然后使用 JLabelsetIcon(...) 方法更新图像。

上述建议需要重新设计您的应用程序。我建议您从 Swing 教程中的 How to Use Combo Boxes 部分中找到的 ComboBoxDemo 开始。

是的,示例使用了组合框,但概念是相同的。在两种情况下,您都使用 ActionListener 来更改图像。在演示中,ActionListener 添加到了组合框。在您的情况下,ActionListener 添加到了菜单项。


<details>
<summary>英文:</summary>
private void p_add() {
panel.setBounds(0,0,48,48);    
panel.setBackground(Color.black);
ImageIcon imageIcon = new ImageIcon(fitimage(placeholder, panel.getWidth(), panel.getHeight()));
JLabel jl = new JLabel(imageIcon);
panel.add(jl);
f.add(panel);
}
The problem is that you keep adding components to the frame and because of Swing painting logic you don&#39;t see the newly added component.
1. Don&#39;t use setBounds(). Swing was designed to be used with layout managers.
2. Don&#39;t keep creating new components. You should create an add the `JLabel` to the frame in the constructor of your class. Then in your ActionListener you just create a new `ImageIcon` and then use the `setIcon(...)` method of the `JLabel` to update the image.
The above suggestions will require a redesign of your application. I suggest you start with the `ComboBoxDemo` found in the section from the Swing tutorial on [How to Use Combo Boxes](https://docs.oracle.com/javase/tutorial/uiswing/components/combobox.html). 
Yes the example uses a combo box, but the concept is the same. In both cases you use an ActionListener to change the image. In the demo, the ActionListener is added to the combo box. In your case the ActionListener is added to the menu item.
</details>

huangapple
  • 本文由 发表于 2020年10月20日 04:20:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/64434616.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定