在 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.
}
}
我有一个随机涂有 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.
}
}