Java 使用ActionListener添加新元素
大家好,我有一个按钮,可以在我设置的ArrayList中添加一个新球。而不是添加一个新的球,它只是加快了球,我已经去。 此CreateCircle创建球:Java 使用ActionListener添加新元素,java,swing,arraylist,jpanel,Java,Swing,Arraylist,Jpanel,大家好,我有一个按钮,可以在我设置的ArrayList中添加一个新球。而不是添加一个新的球,它只是加快了球,我已经去。 此CreateCircle创建球: import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; @SuppressWarnings("serial") public class CreateCircle extends JPanel { /* Ports J
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class CreateCircle extends JPanel {
/* Ports JFrame width, height from BouncingDrawFrame */
static double c, d;
/* Ports desired size of Circle */
static int r = 20; // Initial Value 20
/* Ports timer delay from BouncingDrawFrame */
static int z = 10; // Initial Value 10
/* Timer to control speed */
static Timer t = new Timer(z, null);
/* X,Y points to start, speed of movement */
static double x, y, velX = 1, velY = 1;
/* Ports color choice from BouncingDrawFrame */
static Color myColor;
public CreateCircle(int a, int b) {
/* Height of Frame */
c = a;
/* Width of Frame */
d = b;
t.start();
t.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
/* "Bounces" the Ball off the sides */
if (x < 0 || x > (d - (r + 2))) {
velX = -velX;
}
/* "Bounces" the Ball off the top and bottom */
if (y < 0 || y > (c - (r + 30))) {
velY = -velY;
}
/* Moves ball 2 pixels each timer action */
x += velX;
y += velY;
repaint();
}
});
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D circle = new Ellipse2D.Double(x, y, r, r);
g2.setColor(myColor);
g2.fill(circle);
}
}
CreateCircle
类中的每个字段都是static
,这意味着它们在CreateCircle
的所有实例之间共享。本质上这意味着你对其中一个球所做的每一次计算都发生在每个球上,每个球都是一样的
如果希望这些属性与CreateCircle
的特定实例相关联,则必须将这些属性设置为非静态
您可能希望查看有关实例和类成员的官方教程
根据您的问题更新如下:flicker:我创建了一个反弹jlabel的示例(),展示了如何做到这一点,并让Swing负责重新绘制等。这里也有:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class BouncingLabels extends JFrame {
// this is our bouncing label component. it bounces around its parent. this could
// be pulled out into its own class file; its in here to keep the example self
// contained.
static class BouncingLabel extends JLabel {
private int fieldWidth, fieldHeight; // width/height of parent at creation time.
private int velX = 1, velY = 1; // current x and y velocity.
// constructor sets base label properties and starts a timer.
public BouncingLabel (int fieldWidth, int fieldHeight) {
this.fieldWidth = fieldWidth;
this.fieldHeight = fieldHeight;
setBounds(0, 0, 60, 20);
setOpaque(true);
setBackground(Color.RED);
setForeground(Color.WHITE);
setText("HELLO");
setVisible(true);
// timer will call step() every 10ms.
new Timer(10, new ActionListener() {
@Override public void actionPerformed (ActionEvent e) {
step();
}
}).start();
}
// step updates the component position. note that no explicit painting is done.
private void step () {
int x = getX();
int y = getY();
int maxx = fieldWidth - getWidth();
int maxy = fieldHeight - getHeight();
x += velX;
y += velY;
if ((x >= maxx && velX > 0) || (x <= 0 && velX < 0))
velX = -velX;
if ((y >= maxy && velY > 0) || (y <= 0 && velY < 0))
velY = -velY;
setLocation(x, y);
}
}
// BouncingLabels is our main frame; click on it to add a label.
public BouncingLabels () {
// work with the content pane, not the frame itself.
final Container c = getContentPane();
c.setPreferredSize(new Dimension(300, 300));
c.setLayout(null);
setResizable(false);
pack();
// add an initial bouncing object.
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
// clicking on the frame will add a new object.
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked (MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1)
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
}
});
}
// main method creates and shows a BouncingLabels frame.
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run () {
BouncingLabels b = new BouncingLabels();
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.setLocationRelativeTo(null);
b.setVisible(true);
}
});
}
}
导入java.awt.Color;
导入java.awt.Container;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingUtilities;
导入javax.swing.Timer;
@抑制警告(“串行”)
公共类BouncingLabels扩展JFrame{
//这是我们的反弹标签组件。它围绕其父对象反弹。这可能会
//被拖出到它自己的类文件中;在这里保存示例本身
//包含。
静态类BouncingLabel扩展了JLabel{
private int fieldWidth,fieldHeight;//创建时父项的宽度/高度。
private int velX=1,velY=1;//当前的x和y速度。
//构造函数设置基本标签属性并启动计时器。
公共BouncingLabel(int fieldWidth、int fieldHeight){
this.fieldWidth=fieldWidth;
this.fieldHeight=fieldHeight;
立根(0,0,60,20);
set不透明(true);
挫折地面(颜色:红色);
设置前景(颜色:白色);
setText(“你好”);
setVisible(真);
//计时器将每隔10毫秒调用步骤()。
新计时器(10,新ActionListener(){
@覆盖已执行的公共无效操作(ActionEvent e){
步骤();
}
}).start();
}
//步骤更新组件位置。请注意,没有进行显式绘制。
私有无效步骤(){
intx=getX();
int y=getY();
int maxx=fieldWidth-getWidth();
int maxy=fieldHeight-getHeight();
x+=velX;
y+=0;
如果((x>=maxx&&velX>0)| |(x=maxy&&velY>0)|(y您的CreateCircle
类中的每个字段都是静态的
,这意味着它们在CreateCircle
的所有实例之间共享。本质上,这意味着您对其中一个球所做的每个计算都发生在每个球上,并且每个球都是相同的
如果希望这些属性与CreateCircle
的特定实例相关联,则必须将这些属性设置为非静态
您可能希望查看有关实例和类成员的官方教程
根据您的问题更新如下:闪烁:我创建了一个反弹JLabel的示例(),展示了如何做到这一点,并让Swing负责重新绘制等。这里还有:
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class BouncingLabels extends JFrame {
// this is our bouncing label component. it bounces around its parent. this could
// be pulled out into its own class file; its in here to keep the example self
// contained.
static class BouncingLabel extends JLabel {
private int fieldWidth, fieldHeight; // width/height of parent at creation time.
private int velX = 1, velY = 1; // current x and y velocity.
// constructor sets base label properties and starts a timer.
public BouncingLabel (int fieldWidth, int fieldHeight) {
this.fieldWidth = fieldWidth;
this.fieldHeight = fieldHeight;
setBounds(0, 0, 60, 20);
setOpaque(true);
setBackground(Color.RED);
setForeground(Color.WHITE);
setText("HELLO");
setVisible(true);
// timer will call step() every 10ms.
new Timer(10, new ActionListener() {
@Override public void actionPerformed (ActionEvent e) {
step();
}
}).start();
}
// step updates the component position. note that no explicit painting is done.
private void step () {
int x = getX();
int y = getY();
int maxx = fieldWidth - getWidth();
int maxy = fieldHeight - getHeight();
x += velX;
y += velY;
if ((x >= maxx && velX > 0) || (x <= 0 && velX < 0))
velX = -velX;
if ((y >= maxy && velY > 0) || (y <= 0 && velY < 0))
velY = -velY;
setLocation(x, y);
}
}
// BouncingLabels is our main frame; click on it to add a label.
public BouncingLabels () {
// work with the content pane, not the frame itself.
final Container c = getContentPane();
c.setPreferredSize(new Dimension(300, 300));
c.setLayout(null);
setResizable(false);
pack();
// add an initial bouncing object.
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
// clicking on the frame will add a new object.
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked (MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1)
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
}
});
}
// main method creates and shows a BouncingLabels frame.
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run () {
BouncingLabels b = new BouncingLabels();
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.setLocationRelativeTo(null);
b.setVisible(true);
}
});
}
}
导入java.awt.Color;
导入java.awt.Container;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.SwingUtilities;
导入javax.swing.Timer;
@抑制警告(“串行”)
公共类BouncingLabels扩展JFrame{
//这是我们的反弹标签组件。它围绕其父对象反弹。这可能会
//被拖出到它自己的类文件中;在这里保存示例本身
//包含。
静态类BouncingLabel扩展了JLabel{
private int fieldWidth,fieldHeight;//创建时父项的宽度/高度。
private int velX=1,velY=1;//当前的x和y速度。
//构造函数设置基本标签属性并启动计时器。
公共BouncingLabel(int fieldWidth、int fieldHeight){
this.fieldWidth=fieldWidth;
this.fieldHeight=fieldHeight;
立根(0,0,60,20);
set不透明(true);
挫折地面(颜色:红色);
设置前景(颜色:白色);
setText(“你好”);
setVisible(真);
//计时器将每隔10毫秒调用步骤()。
新计时器(10,新ActionListener(){
@覆盖已执行的公共无效操作(ActionEvent e){
步骤();
}
}).start();
}
//步骤更新组件位置。请注意,没有进行显式绘制。
私有无效步骤(){
intx=getX();
int y=getY();
int maxx=fieldWidth-getWidth();
int maxy=fieldHeight-getHeight();
x+=velX;
y+=0;
如果((x>=maxx&&velX>0)| |(x=maxy&&velY>0)|(y)你过度使用了静态修饰符。编辑--我现在看到Jason C在答案中陈述。1+到他的答案。你过度使用了静态修饰符。编辑--我现在看到Jason C在答案中陈述。1+到他的答案。谢谢你的工作,我从所有变量和字段中删除了静态修饰符,但是现在当我创建一个新的球时,它会闪烁。我需要把repaint()放在任何地方吗?你的代码有很多问题,尤其是每一个问题
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class BouncingLabels extends JFrame {
// this is our bouncing label component. it bounces around its parent. this could
// be pulled out into its own class file; its in here to keep the example self
// contained.
static class BouncingLabel extends JLabel {
private int fieldWidth, fieldHeight; // width/height of parent at creation time.
private int velX = 1, velY = 1; // current x and y velocity.
// constructor sets base label properties and starts a timer.
public BouncingLabel (int fieldWidth, int fieldHeight) {
this.fieldWidth = fieldWidth;
this.fieldHeight = fieldHeight;
setBounds(0, 0, 60, 20);
setOpaque(true);
setBackground(Color.RED);
setForeground(Color.WHITE);
setText("HELLO");
setVisible(true);
// timer will call step() every 10ms.
new Timer(10, new ActionListener() {
@Override public void actionPerformed (ActionEvent e) {
step();
}
}).start();
}
// step updates the component position. note that no explicit painting is done.
private void step () {
int x = getX();
int y = getY();
int maxx = fieldWidth - getWidth();
int maxy = fieldHeight - getHeight();
x += velX;
y += velY;
if ((x >= maxx && velX > 0) || (x <= 0 && velX < 0))
velX = -velX;
if ((y >= maxy && velY > 0) || (y <= 0 && velY < 0))
velY = -velY;
setLocation(x, y);
}
}
// BouncingLabels is our main frame; click on it to add a label.
public BouncingLabels () {
// work with the content pane, not the frame itself.
final Container c = getContentPane();
c.setPreferredSize(new Dimension(300, 300));
c.setLayout(null);
setResizable(false);
pack();
// add an initial bouncing object.
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
// clicking on the frame will add a new object.
addMouseListener(new MouseAdapter() {
@Override public void mouseClicked (MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1)
c.add(new BouncingLabel(c.getWidth(), c.getHeight()));
}
});
}
// main method creates and shows a BouncingLabels frame.
public static void main (String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override public void run () {
BouncingLabels b = new BouncingLabels();
b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
b.setLocationRelativeTo(null);
b.setVisible(true);
}
});
}
}