Java 如何使用actionListener更改JButton的颜色
我有以下JFrame。 它包含一个由正方形和圆形按钮组成的按钮[100]。我想在单击它们时更改它们的颜色。所以我使用actionListener来实现这一点。但是当我编写actionListener来更改颜色时,它给了我一个例外 线程“AWT-EventQueue-0”java.lang.ArrayIndexOutofBounds异常:索引100超出长度100的界限 它说在b[i].setBackground(Color.blue)是个例外;在actionListener内部。 我搜索了很多,没有任何东西改变颜色,只是给出了一个例外。 这是我的密码 Subject.javaJava 如何使用actionListener更改JButton的颜色,java,swing,jbutton,Java,Swing,Jbutton,我有以下JFrame。 它包含一个由正方形和圆形按钮组成的按钮[100]。我想在单击它们时更改它们的颜色。所以我使用actionListener来实现这一点。但是当我编写actionListener来更改颜色时,它给了我一个例外 线程“AWT-EventQueue-0”java.lang.ArrayIndexOutofBounds异常:索引100超出长度100的界限 它说在b[i].setBackground(Color.blue)是个例外;在actionListener内部。 我搜索了很多,
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class Subject extends JFrame{
public Subject() {
super("Subject");
p = new JPanel(new GridLayout(10,10));
b = new JButton[100];
Random r = new Random();
for(i=0;i<100;i++) {
y = r.nextInt(2) +1;
if(y==1) {
b[i] = new JButton();
b[i].setBackground(Color.black);
b[i].setPreferredSize(new Dimension(35,35));
p.add(b[i]);
}else {
b[i] = new Circle();
b[i].setBackground(Color.black);
p.add(b[i]);
}
b[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
b[i].setBackground(Color.blue);
}
});
}
add(p);
pack();
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocation(100,200);
}
private JPanel p;
private JButton[] b;
private int i, y;
}
import java.awt.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class Circle extends JButton{
public Circle() {
setBackground(Color.red);
setFocusable(false);
/*
These statements enlarge the button so that it
becomes a circle rather than an oval.
*/
Dimension size = getPreferredSize();
size.width = size.height = Math.min(35,35);
setPreferredSize(size);
/*
This call causes the JButton not to paint the background.
This allows us to paint a round background.
*/
setContentAreaFilled(false);
}
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) {
g.setColor(Color.yellow);
} else {
g.setColor(getBackground());
}
g.fillOval(0, 0, getSize().width - 1, getSize().height - 1);
JLabel l = new JLabel("Click Me");
super.paintComponent(g);
}
protected void paintBorder(Graphics g) {
g.setColor(Color.darkGray);
g.drawOval(0, 0, getSize().width - 1, getSize().height - 1);
}
// Hit detection.
Shape shape;
public boolean contains(int x, int y) {
// If the button has changed size, make a new shape object.
if (shape == null || !shape.getBounds().equals(getBounds())) {
shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
}
我也尝试了以下方法,但没有任何改变
b[i].addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()==b[i])
{
b[i].setBackground(Color.blue);
}
}
});
有人对如何修复它有什么建议吗?谢谢大家! 只需更改
actionPerformed()方法中的以下行即可
b[i].挫折背景(颜色.蓝色);
对此
((JButton)e.getSource()).setBackground(Color.blue);
您正在为每个JButton
创建一个单独的匿名类(实现ActionListener
接口)。因此,ActionEvent
源只能是为其创建匿名类的JButton
请注意,编译java代码后,每个ActionListener
都有一个单独的类文件。类文件名将以Subject$
开头,以.class
结尾,例如:
Subject$1.class
Subject$2.class
Subject$3.class
因为您已经为每个JButton
创建了一个类,所以至少会有100个此类,只需在actionPerformed()
方法中更改以下行即可
b[i].挫折背景(颜色.蓝色);
对此
((JButton)e.getSource()).setBackground(Color.blue);
您正在为每个JButton
创建一个单独的匿名类(实现ActionListener
接口)。因此,ActionEvent
源只能是为其创建匿名类的JButton
请注意,编译java代码后,每个ActionListener
都有一个单独的类文件。类文件名将以Subject$
开头,以.class
结尾,例如:
Subject$1.class
Subject$2.class
Subject$3.class
既然您已经为每个JButton
创建了一个类,那么至少会有100个这样的类。您是否也可以在更改背后加入推理,以便OP(和其他读者)知道应该避免什么错误?@Abra谢谢。我从来没有想过要这样做that@knowsnothing,将至少有100个这样的类-因此更好的实现是不要为每个按钮创建唯一的ActionListener。相反,ActionListener应该在循环外部创建,然后您只需为每个按钮共享相同的ActionListener。请参阅:关于这种方法的一个工作示例。您是否也可以包括这种更改背后的原因,以便OP(和其他读者)知道应该避免什么错误?@Abra谢谢。我从来没有想过要这样做that@knowsnothing,将至少有100个这样的类-因此更好的实现是不要为每个按钮创建唯一的ActionListener。相反,ActionListener应该在循环外部创建,然后您只需为每个按钮共享相同的ActionListener。请参阅:此方法的一个工作示例。有关为什么要面向java.lang.ArrayIndexOutOfBoundsException:Index 100
,这是因为在b[i]处。挫折背景(Color.blue)
您使用的是i
,这是一个类字段,循环结束后将保存值100
,使每个侦听器都希望执行b[100]。setBackground(…)
。现在的问题是:你们为什么要把它变成一个领域?是因为当您在for(int i=0;…)中声明i
时,编译器抱怨匿名类只能访问最终或有效的最终局部变量吗?为什么您要面对java.lang.arrayindexoutofbounds异常:索引100
是因为在b[i].setBackground(Color.blue)
您使用的是i
,这是一个类字段,循环结束后将保存值100
,使每个侦听器都希望执行b[100]。setBackground(…)
。现在的问题是:你们为什么要把它变成一个领域?是因为当您在for(int i=0;…)
编译器中声明i
时,匿名类只能访问最终或有效的最终局部变量吗?