在 ActionPerformed 中调用非局部变量

Calling non-local variable in ActionPerformed

我有一个随机涂有 3 种不同颜色(蓝色、红色和绿色)的圆圈和 3 个具有相同颜色(蓝色、红色和绿色)的按钮,如果圆圈是红色的,我按下我需要的红色按钮如果您选择了错误的颜色,就会出现在 YOU WON 的标签中。这非常简单,但我无法在 ActionPerformed 中调用来自 paintComponent 的变量(即与按钮匹配的颜色)。也为我的语言感到抱歉。

这是带有 2 类 的代码:

PaintPanel.class

public class PaintPanel extends JPanel implements ActionListener {

int x = 200, y = 250;
private JButton b1 = new JButton("BLUE");
private JButton b2 = new JButton("RED");
private JButton b3 = new JButton("GREEN");
 JLabel label = new JLabel("Choose the right Color");
 JPanel subPanel = new JPanel();
private Color[] colors;

public PaintPanel() {

    setLayout(new BorderLayout());
    setPreferredSize(new Dimension(440, 440));
    add(label, BorderLayout.NORTH);
    b1.addActionListener(this);
    b2.addActionListener(this);
    b3.addActionListener(this);
    subPanel.add(b1);
    b1.setForeground(Color.BLUE);
    subPanel.add(b2);
    b2.setForeground(Color.RED);
    subPanel.add(b3);
    b3.setForeground(Color.GREEN);
    add(subPanel, BorderLayout.SOUTH);

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Color[] colors = new Color[3];

    colors[0] = Color.BLUE;
    colors[1] = Color.RED;
    colors[2] = Color.GREEN;

    Color c1 = colors[randInt(colors.length)];


    g.setColor(c1);
    /* this.colors.equals(c1); !!!! HERE I TRIED !!!*/
    g.fillOval(x, y, 30, 30);

}

private int randInt(int length) {
    // TODO Auto-generated method stub
    Random rand = new Random();
    int randomColor = rand.nextInt(length);
    return randomColor;
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
    }else {
        label.setText("You LOSE");
    } 
    if (e.getSource() == b2) {

    }
    if (e.getSource() == b3) {

    }
}
}

另一个 - DrawCircle.class -

public class DrawCircle extends JFrame {

private JPanel painted;

public DrawCircle() {
    painted = new PaintPanel();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLayout(new FlowLayout());
    setBounds(0, 0, 800, 540);
    add(painted);
    setVisible(true);
}

public static void main(String[] args) {
    new DrawCircle();

}

}

我认为您只是弄乱了牙套(和缩进)。请在 IDE 中使用自动缩进或自动格式化工具,它会快速定位这些问题。

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
//  v Problem is this extra brace
    }else {
        label.setText("You LOSE");
    } 

改为

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getSource() == b1) {
        if (Color.BLUE.equals(colors)) {
            label.setText("You WIN");
        }
        else {
          label.setText("You LOSE");
        } 
    } else if( //...

不应在 paintComponent() 方法中创建颜色数组。它应声明为 PaintPanel 实例变量,并应在 PaintPanel 构造函数中创建。

这里有一个可能性(你不需要单独的 class;我在 PaintPanel 中添加了一个 main):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class PaintPanel extends JPanel implements ActionListener {

   int             x        = 200, y = 250;
   private JButton b1       = new JButton("BLUE");
   private JButton b2       = new JButton("RED");
   private JButton b3       = new JButton("GREEN");
   JLabel          label    = new JLabel("Choose the right Color");
   JPanel          subPanel = new JPanel();
   private Color   circleColor;

   public PaintPanel() {

      setLayout(new BorderLayout());
      setPreferredSize(new Dimension(440, 440));
      add(label, BorderLayout.NORTH);
      b1.addActionListener(this);
      b2.addActionListener(this);
      b3.addActionListener(this);
      subPanel.add(b1);
      b1.setForeground(Color.BLUE);
      subPanel.add(b2);
      b2.setForeground(Color.RED);
      subPanel.add(b3);
      b3.setForeground(Color.GREEN);
      add(subPanel, BorderLayout.SOUTH);

      Random rand = new Random();
      int rc = rand.nextInt(3);
      switch (rc) {
      case 1:
         circleColor = Color.RED;
         break;
      case 2:
         circleColor = Color.GREEN;
         break;
      default:
         circleColor = Color.BLUE;
         break;
      }

   }

   @Override
   public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(circleColor);
      g.fillOval(x, y, 30, 30);

   }

   @Override
   public void actionPerformed(ActionEvent e) {
      JButton b = (JButton) e.getSource();
      if (b.getForeground().equals(circleColor)) {
         label.setText("You WIN");
      } else {
         label.setText("You LOSE");
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            // create the main frame
            JFrame frame = new JFrame();
            // create the component to display in the frame
            PaintPanel comp = new PaintPanel();
            frame.add(comp, BorderLayout.CENTER);

            frame.pack();
            frame.setVisible(true);
            frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
            frame.addWindowListener(new WindowAdapter() {
               @Override
               public void windowClosing(WindowEvent arg0) {
                  System.exit(0);
               }
            });
         }
      });

   }
}

请注意几点:您不能从静态上下文访问非静态方法。考虑将您的 DrawCircle() 方法放在单独的 class 中。创建该 class 的实例并从该实例调用 DrawCircle()

关于 PaintPanel.class 请注意 paintComponent() 调用非常频繁,而不仅仅是在初始化时调用。您生成的颜色需要保存在 actionPerformed() 可访问的位置。考虑在您的 class 结构中创建一个 Color tmp 成员,并从那里引用您的正确答案。此外,您似乎错过了对 UpdateUI() 的调用。这段代码并不完美,但效果很好。就个人而言,除了覆盖 paintComponent() 之外,我会找到一种生成新颜色的不同方法,但如果您在那里需要它,这个示例应该会有所帮助。在下方评论改进:

package com.company;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class PaintPanel extends JPanel implements ActionListener
{

    int x = 200, y = 250;
    private JButton b1 = new JButton("BLUE");
    private JButton b2 = new JButton("RED");
    private JButton b3 = new JButton("GREEN");
    JLabel label = new JLabel("Choose the right Color");
    JPanel subPanel = new JPanel();
    private Color[] colors;
    Color tmp = null;

    public PaintPanel()
    {

        setLayout(new BorderLayout());
        setPreferredSize(new Dimension(440, 440));
        add(label, BorderLayout.NORTH);
        b1.addActionListener(this);
        b2.addActionListener(this);
        b3.addActionListener(this);
        subPanel.add(b1);
        b1.setForeground(Color.BLUE);
        subPanel.add(b2);
        b2.setForeground(Color.RED);
        subPanel.add(b3);
        b3.setForeground(Color.GREEN);
        add(subPanel, BorderLayout.SOUTH);

    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        colors = new Color[3]; //Referencing Class member colors instead of local variable
        colors[0] = Color.BLUE;
        colors[1] = Color.RED;
        colors[2] = Color.GREEN;

        tmp = colors[randInt(colors.length)]; //Read into a class member instead of a local variable
        g.setColor(tmp);
        System.out.println("Paint Triggered. New Color is: " + tmp.toString()); //todo remove this debugging line
        g.fillOval(x, y, 30, 30);
    }

    private int randInt(int length)
    {
        // TODO Auto-generated method stub
        Random rand = new Random();
        int randomColor = rand.nextInt(length);
        return randomColor;
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource() == b1) {
            if (Color.BLUE.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        } else if (e.getSource() == b2) {
            if (Color.RED.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        } else if (e.getSource() == b3) {
            if (Color.GREEN.equals(tmp)) {
                label.setText("You WIN");
            } else {
                label.setText("You Loose");
            }
        }
        updateUI(); //<---------------IMPORTANT To Sync What you see with each button press.
    }
}