按jbutton java

时间:2017-11-23 16:11:46

标签: java swing jbutton imageicon

您好我的代码遇到了问题,我一直试图弄清楚几天有什么问题,并查看了一些相关程序的帮助,但无法弄明白。该程序应根据您按下的按钮更改交通信号灯的图像:红色,黄色或绿色。有3个班级。我在eclipse中运行程序。 CLass 1包含主要方法的trafficLight:

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);
   }
}

包含imageicons部分的第二类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;
    }
}

包含jbuttons的第三类trafficLightControl:

//********************************************************************
// 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();
        }
    }
}

nonePic.png the non lit up traffic light image redPic.png of traffic light lit up with red yellowPic.png greenPic.png

每次单击按钮时,都应该将trafficLightPanel对象中的计数设置为与颜色对应的计数,然后根据计数将图像替换为相应的图像。这些组件都是用盒子布局放在一起的。

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

我想也许计数出了点问题,我尝试做一些像添加jLabel的东西,每次使用盒子布局显示计数但是它没有显示任何东西(这个尝试不在代码中) )。我也尝试将jLabel放入trafficLightControls类并将其与add(红色)add(黄色)一起添加....但它不会显示任何内容。我尝试的另一件事是每次更改按钮的文本以显示带有计数的颜色作为jLabel尝试的替代。我尝试在侦听器类中使用.setText("")方法,如red.setText("")为红色。我很感激,如果有人能解释如何添加一个jLabel并更改按钮的文本,就像我在这个特别的小段落中所描述的那样,因为我想知道如何做以备将来参考,尽管它是没有必要解决我的问题所以可以不用这个小段落。

非常感谢任何人的帮助!

编辑:(对不起,我留下了我试图让jLabel测试代码但我删除它们的遗留物,虽然它们没有影响我认为的代码,但是由于我的问题,我试图使用它们。我是非常抱歉,如果这让任何人感到困惑)

1 个答案:

答案 0 :(得分:1)

如果你所做的只是交换ImageIcons,则无需拨打repaint()即可覆盖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);
        }
    }    
}