按 j 按钮更改图像 java

Changing Image by pressing jbutton java

你好,我的代码有问题,这几天我一直在努力找出问题所在,并查看了一些相关的程序寻求帮助,但无法弄清楚。该程序应该根据您按下的按钮更改交通信号灯的图像:红色、黄色或绿色。有 3 个 class。我是运行eclipse中的程序。 CLass 1 个包含主要方法的交通信号灯:

import javax.swing.*;
import java.awt.*;
public class trafficLight
{
   //-----------------------------------------------------------------
   //  Creates and displays the main program frame.
   //-----------------------------------------------------------------
   public static void main(String[] args)
   {
      JFrame frame = new JFrame("CHANGE TRAFFIC LIGHT");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      trafficLightPanel lights = new trafficLightPanel();
      trafficLightControls controls = new trafficLightControls(lights);

      JPanel panel = new JPanel();
      panel.setBackground(Color.blue);
      panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));



      panel.add(Box.createRigidArea (new Dimension (0, 20)));
      panel.add(lights);
      panel.add(Box.createRigidArea (new Dimension (0, 10)));
      panel.add(controls);
      panel.add(Box.createRigidArea (new Dimension (0, 10)));

      frame.getContentPane().add(panel);
      frame.pack();
      frame.setVisible(true);
   }
}

包含图像图标部分的第二个 class trafficLightPanel:

import java.awt.*;
import javax.swing.*;
public class trafficLightPanel extends JPanel
{
    public int count, redCount, yellowCount, greenCount;
    private ImageIcon none, red, yellow, green;
    private JLabel imageLabel;
    //-----------------------------------------------------------------
    // Constructor: Sets up the images and the initial state.
    //-----------------------------------------------------------------
    public trafficLightPanel()
    {

        none = new ImageIcon("nonePic.png");
        red = new ImageIcon("redPic.png");
        yellow = new ImageIcon("yellowPic.png");
        green = new ImageIcon("greenPic.png");
        setBackground(Color.black);
        redCount = 1; yellowCount = 2; greenCount = 3;

        imageLabel = new JLabel(none);

        add(imageLabel);

    }
    //-----------------------------------------------------------------
    // Paints the panel using the appropriate image.
    //-----------------------------------------------------------------
    public void paintComponent(Graphics page)
    {
        super.paintComponent(page);

        if (count == redCount)
        {
            imageLabel.setIcon(red);
        }
        if (count == yellowCount)
        {
            imageLabel.setIcon(yellow);
        }
        if (count == greenCount)
        {
            imageLabel.setIcon(green);
        }
    }
    //-----------------------------------------------------------------
    // Sets the status of the traffic light.
    //-----------------------------------------------------------------
    public void setCount(int newCount)
    {
         count = newCount;
    }
}

包含 jbutton 的第三个 class trafficLightControls:

//********************************************************************
// Represents the control panel for the traffic light program.
//********************************************************************
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class trafficLightControls extends JPanel
{
    private trafficLightPanel lights;
    private JButton red, yellow, green;
    //-----------------------------------------------------------------
    // Sets up the traffic light control panel.
    //-----------------------------------------------------------------
    public trafficLightControls(trafficLightPanel lightPanel)
    {
            lights = lightPanel;
            red = new JButton("RED");
            red.addActionListener(new redListener());
            yellow = new JButton("YELLOW");
            yellow.addActionListener(new yellowListener());
            green = new JButton("GREEN");
            green.addActionListener(new greenListener());

            setBackground(Color.black);
            add(red);
            add(yellow);
            add(green);

    }
    //*****************************************************************
    // Represents the listener for the red button.
    //*****************************************************************
    private class redListener implements ActionListener
    {
        //--------------------------------------------------------------
        // sets count to redCount and repaints the lights panel.
        //--------------------------------------------------------------
        public void actionPerformed(ActionEvent event)
        {
            lights.setCount(lights.redCount);
            lights.repaint();
        }
    }
    //*****************************************************************
    //Represents the listener for the yellow button.
    //*****************************************************************
    private class yellowListener implements ActionListener
    {
        //--------------------------------------------------------------
        //sets count to yellowCount and repaints the lights panel.
        //--------------------------------------------------------------
        public void actionPerformed(ActionEvent event)
        {
            lights.setCount(lights.yellowCount);
            lights.repaint();
        }
    }
    //*****************************************************************
    //Represents the listener for the green button.
    //*****************************************************************
    private class greenListener implements ActionListener
    {
        //--------------------------------------------------------------
        //sets count to green count and repaints the lights panel.
        //--------------------------------------------------------------
        public void actionPerformed(ActionEvent event)
        {
            lights.setCount(lights.greenCount);
            lights.repaint();
        }
    }
}

每次我点击一个按钮,它应该将 trafficLightPanel 对象中的计数,灯,设置为与颜色对应的计数,然后根据计数将图像替换为相应的图像.组件全部放在一起,采用盒式布局。

出于某种原因,只有红色会起作用...它开始显示 nonePic,没有任何光线,当我单击红色时,它显示 redPic。如果我在单击红色按钮之前或之后单击任何一个,则其他按钮不显示。如果我先点击其中一个然后点击红色按钮,由于某种原因红色仍然可以显示。所有图像都在根文件夹中(这是正确的名称吗?),该文件夹包含 src 和 bin 文件夹。

我认为计数可能有问题,我尝试做一些事情,比如添加一个每次都会显示计数的 jLabel 到带有框布局的程序中,但它不显示任何内容(此尝试不在编码)。我还尝试将 jLabel 放入 trafficLightControls class 并将其与 add(red) add(yellow) 一起添加......但它不会显示任何内容。我尝试的另一件事是每次都更改按钮的文本以显示带有计数的颜色,作为 jLabel 尝试的替代方法。我尝试在侦听器 class 中使用 .setText("") 方法,如 red.setText("") 用于红色。如果有人能解释如何添加 jLabel 并更改按钮的文本,我将不胜感激,因为我想知道如何做以供将来参考,尽管它是没有必要解决我的问题,所以可以不帮助解决这个小段落。

非常感谢您提供的任何帮助!

编辑:(很抱歉,我留下了我尝试制作 jLabel 来测试代码的残余,但我删除了它们,尽管我相信它们不会影响代码,但由于我的问题,我尝试使用它们。如果这让任何人感到困惑,我非常抱歉)

没有必要调用 repaint() 并且如果您所做的只是交换 ImageIcons,则不应覆盖 paintComponent。只需在 JLabel 上调用 setIcon(...) 即可。该模型将触发视图本身的重绘。

摆脱你的 paintComponent 覆盖并将 setCount 更改为尽可能简单的东西:

public void setCount(int newCount) {
    count = newCount;
    Icon icon = null;
    switch (count) {
    case 1:
        icon = red;
        break;
    case 2:
        icon = yellow;
        break;
    case 3: 
        icon = green;
        break;
    default:
        icon = null;
        break;
    }
    imageLabel.setIcon(icon);
}

例如我的 MCVE,它使用枚举和 Map 来稍微简化代码。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

import javax.swing.*;

@SuppressWarnings("serial")
public class Traff2 extends JPanel {
    public Traff2() {
        Traff2LightPanel lightPanel = new Traff2LightPanel();
        Traff2LightControlsPanel controlsPanel = new Traff2LightControlsPanel(lightPanel);

        setLayout(new BorderLayout());
        add(lightPanel, BorderLayout.CENTER);
        add(controlsPanel, BorderLayout.PAGE_END);
    }

    private static void createAndShowGui() {
        Traff2 mainPanel = new Traff2();

        JFrame frame = new JFrame("Traffic");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

enum Light {
    NONE(""), RED("Red"), YELLOW("Yellow"), GREEN("Green");

    private String text;

    private Light(String text) {
        this.text = text;
    }

    public String getText() {
        return text;
    }
}

@SuppressWarnings("serial")
class Traff2LightPanel extends JPanel {
    private Map<Light, Icon> lightColorMap = new EnumMap<>(Light.class);
    private JLabel imageLabel = new JLabel();
    private Light light = Light.NONE;

    public Traff2LightPanel() {
        // fill the map
        lightColorMap.put(Light.NONE, new ImageIcon("nonePic.png"));
        lightColorMap.put(Light.RED, new ImageIcon("redPic.png"));
        lightColorMap.put(Light.YELLOW, new ImageIcon("yellowPic.png"));
        lightColorMap.put(Light.GREEN, new ImageIcon("greenPic.png"));

        imageLabel.setIcon(lightColorMap.get(Light.NONE));
        add(imageLabel);
    }

    // when changing the light field, 
    // also set the ImageIcon
    public void setLight(Light light) {
        this.light = light;
        imageLabel.setIcon(lightColorMap.get(light));
    }

    public Light getLight() {
        return light;
    }
}

@SuppressWarnings("serial")
class Traff2LightControlsPanel extends JPanel {
    private Traff2LightPanel lightPanel;

    public Traff2LightControlsPanel(Traff2LightPanel lightPanel) {
        this.lightPanel = lightPanel;
        for (Light light : Light.values()) {
            if (light == Light.NONE) {
                continue;
            }
            add(new JButton(new LightAction(light)));
        }
    }

    // use an AbstractAction... 
    // like an ActionListener on "steroids"
    private class LightAction extends AbstractAction {
        private Light light;

        public LightAction(Light light) {
            super(light.getText());
            this.light = light;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            lightPanel.setLight(light);
        }
    }    
}