Starting animation with a button Java Swing
I'd like to create an animation of a few objects ("Spaceships") on the screen, with a start button. This is what I have so far:
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
public static void main(String args)
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
fr.setSize(990,690);
fr.add(game);
game.playingList .add(new Spaceship(3, 0, 570));
game.playingList .add(new Spaceship(1, 250, 570));
game.playingList .add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(game);
fr.add(start,BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
where:
import java.awt.Graphics;
public class Spaceship
int initialSpeed;
int locX, locY; //current location
public Spaceship(int initalSpeed, int initX, int initY)
this.initialSpeed = initalSpeed;
locX = initX;
locY = initY;
public void drawSpaceship(Graphics g)
g.setColor(Color.GREEN);
g.fillOval(locX, locY, 100, 40);
public void moveSpaceship()
locY -= initialSpeed;
Of cousre the idea is that pressing the button would trigger the animation. The problem is that the animation would start automaticaly without the start button being pressed, and then when it ends, the button has no effect. How can I fix this?
java swing button jbutton
add a comment |
I'd like to create an animation of a few objects ("Spaceships") on the screen, with a start button. This is what I have so far:
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
public static void main(String args)
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
fr.setSize(990,690);
fr.add(game);
game.playingList .add(new Spaceship(3, 0, 570));
game.playingList .add(new Spaceship(1, 250, 570));
game.playingList .add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(game);
fr.add(start,BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
where:
import java.awt.Graphics;
public class Spaceship
int initialSpeed;
int locX, locY; //current location
public Spaceship(int initalSpeed, int initX, int initY)
this.initialSpeed = initalSpeed;
locX = initX;
locY = initY;
public void drawSpaceship(Graphics g)
g.setColor(Color.GREEN);
g.fillOval(locX, locY, 100, 40);
public void moveSpaceship()
locY -= initialSpeed;
Of cousre the idea is that pressing the button would trigger the animation. The problem is that the animation would start automaticaly without the start button being pressed, and then when it ends, the button has no effect. How can I fix this?
java swing button jbutton
Do not, ever, start aTimer
inpaintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, theTimer
should be started by some other action, independently of the paint process
– MadProgrammer
Nov 14 '18 at 22:29
The other problem, as far as I can see is, theTimer
and the button are using the sameactionPerformed
method, which doesn't make sense. Provide a method in yourSpaceGame
which can be called by the buttonsActionListener
– MadProgrammer
Nov 14 '18 at 22:31
add a comment |
I'd like to create an animation of a few objects ("Spaceships") on the screen, with a start button. This is what I have so far:
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
public static void main(String args)
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
fr.setSize(990,690);
fr.add(game);
game.playingList .add(new Spaceship(3, 0, 570));
game.playingList .add(new Spaceship(1, 250, 570));
game.playingList .add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(game);
fr.add(start,BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
where:
import java.awt.Graphics;
public class Spaceship
int initialSpeed;
int locX, locY; //current location
public Spaceship(int initalSpeed, int initX, int initY)
this.initialSpeed = initalSpeed;
locX = initX;
locY = initY;
public void drawSpaceship(Graphics g)
g.setColor(Color.GREEN);
g.fillOval(locX, locY, 100, 40);
public void moveSpaceship()
locY -= initialSpeed;
Of cousre the idea is that pressing the button would trigger the animation. The problem is that the animation would start automaticaly without the start button being pressed, and then when it ends, the button has no effect. How can I fix this?
java swing button jbutton
I'd like to create an animation of a few objects ("Spaceships") on the screen, with a start button. This is what I have so far:
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
public static void main(String args)
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
fr.setSize(990,690);
fr.add(game);
game.playingList .add(new Spaceship(3, 0, 570));
game.playingList .add(new Spaceship(1, 250, 570));
game.playingList .add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(game);
fr.add(start,BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
where:
import java.awt.Graphics;
public class Spaceship
int initialSpeed;
int locX, locY; //current location
public Spaceship(int initalSpeed, int initX, int initY)
this.initialSpeed = initalSpeed;
locX = initX;
locY = initY;
public void drawSpaceship(Graphics g)
g.setColor(Color.GREEN);
g.fillOval(locX, locY, 100, 40);
public void moveSpaceship()
locY -= initialSpeed;
Of cousre the idea is that pressing the button would trigger the animation. The problem is that the animation would start automaticaly without the start button being pressed, and then when it ends, the button has no effect. How can I fix this?
java swing button jbutton
java swing button jbutton
asked Nov 14 '18 at 22:22
Ramy LernerRamy Lerner
72
72
Do not, ever, start aTimer
inpaintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, theTimer
should be started by some other action, independently of the paint process
– MadProgrammer
Nov 14 '18 at 22:29
The other problem, as far as I can see is, theTimer
and the button are using the sameactionPerformed
method, which doesn't make sense. Provide a method in yourSpaceGame
which can be called by the buttonsActionListener
– MadProgrammer
Nov 14 '18 at 22:31
add a comment |
Do not, ever, start aTimer
inpaintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, theTimer
should be started by some other action, independently of the paint process
– MadProgrammer
Nov 14 '18 at 22:29
The other problem, as far as I can see is, theTimer
and the button are using the sameactionPerformed
method, which doesn't make sense. Provide a method in yourSpaceGame
which can be called by the buttonsActionListener
– MadProgrammer
Nov 14 '18 at 22:31
Do not, ever, start a
Timer
in paintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, the Timer
should be started by some other action, independently of the paint process– MadProgrammer
Nov 14 '18 at 22:29
Do not, ever, start a
Timer
in paintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, the Timer
should be started by some other action, independently of the paint process– MadProgrammer
Nov 14 '18 at 22:29
The other problem, as far as I can see is, the
Timer
and the button are using the same actionPerformed
method, which doesn't make sense. Provide a method in your SpaceGame
which can be called by the buttons ActionListener
– MadProgrammer
Nov 14 '18 at 22:31
The other problem, as far as I can see is, the
Timer
and the button are using the same actionPerformed
method, which doesn't make sense. Provide a method in your SpaceGame
which can be called by the buttons ActionListener
– MadProgrammer
Nov 14 '18 at 22:31
add a comment |
1 Answer
1
active
oldest
votes
Let's start with the glaringly obvious...
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
Call t.start
inside paintComponent
is a very, very, very bad idea. You do not control the paint process (ie when paintComponent
gets called), so it might be called at any time for any number of reasons, often in quick succession.
You should have a look at Painting in AWT and Swing for more details about how painting works in Swing
Painting should simply paint the current state of the component and nothing else.
The second problem is the fact that both the Timer
and the button are calling the same actionPerformed
method, which doesn't really make sense. In fact, in a perfect world, you wouldn't implement ActionListener
directly like this and instead make use of Anonymous Classes which would guard against outside classes calling the method directly or indirectly.
So, what's the solution? Add a method to your SpaceGame
which can be called to start the animation, something like...
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
public void start()
if (t.isRunning())
return;
t.start();
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Then update your main method to call it...
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53309623%2fstarting-animation-with-a-button-java-swing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Let's start with the glaringly obvious...
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
Call t.start
inside paintComponent
is a very, very, very bad idea. You do not control the paint process (ie when paintComponent
gets called), so it might be called at any time for any number of reasons, often in quick succession.
You should have a look at Painting in AWT and Swing for more details about how painting works in Swing
Painting should simply paint the current state of the component and nothing else.
The second problem is the fact that both the Timer
and the button are calling the same actionPerformed
method, which doesn't really make sense. In fact, in a perfect world, you wouldn't implement ActionListener
directly like this and instead make use of Anonymous Classes which would guard against outside classes calling the method directly or indirectly.
So, what's the solution? Add a method to your SpaceGame
which can be called to start the animation, something like...
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
public void start()
if (t.isRunning())
return;
t.start();
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Then update your main method to call it...
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
add a comment |
Let's start with the glaringly obvious...
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
Call t.start
inside paintComponent
is a very, very, very bad idea. You do not control the paint process (ie when paintComponent
gets called), so it might be called at any time for any number of reasons, often in quick succession.
You should have a look at Painting in AWT and Swing for more details about how painting works in Swing
Painting should simply paint the current state of the component and nothing else.
The second problem is the fact that both the Timer
and the button are calling the same actionPerformed
method, which doesn't really make sense. In fact, in a perfect world, you wouldn't implement ActionListener
directly like this and instead make use of Anonymous Classes which would guard against outside classes calling the method directly or indirectly.
So, what's the solution? Add a method to your SpaceGame
which can be called to start the animation, something like...
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
public void start()
if (t.isRunning())
return;
t.start();
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Then update your main method to call it...
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
add a comment |
Let's start with the glaringly obvious...
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
Call t.start
inside paintComponent
is a very, very, very bad idea. You do not control the paint process (ie when paintComponent
gets called), so it might be called at any time for any number of reasons, often in quick succession.
You should have a look at Painting in AWT and Swing for more details about how painting works in Swing
Painting should simply paint the current state of the component and nothing else.
The second problem is the fact that both the Timer
and the button are calling the same actionPerformed
method, which doesn't really make sense. In fact, in a perfect world, you wouldn't implement ActionListener
directly like this and instead make use of Anonymous Classes which would guard against outside classes calling the method directly or indirectly.
So, what's the solution? Add a method to your SpaceGame
which can be called to start the animation, something like...
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
public void start()
if (t.isRunning())
return;
t.start();
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Then update your main method to call it...
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Let's start with the glaringly obvious...
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
t.start();
Call t.start
inside paintComponent
is a very, very, very bad idea. You do not control the paint process (ie when paintComponent
gets called), so it might be called at any time for any number of reasons, often in quick succession.
You should have a look at Painting in AWT and Swing for more details about how painting works in Swing
Painting should simply paint the current state of the component and nothing else.
The second problem is the fact that both the Timer
and the button are calling the same actionPerformed
method, which doesn't really make sense. In fact, in a perfect world, you wouldn't implement ActionListener
directly like this and instead make use of Anonymous Classes which would guard against outside classes calling the method directly or indirectly.
So, what's the solution? Add a method to your SpaceGame
which can be called to start the animation, something like...
public class SpaceGame extends JPanel implements ActionListener
//The list of spaceships that should be painted
LinkedList<Spaceship> playingList = new LinkedList<Spaceship>();
Timer t = new Timer(5, this);
public void start()
if (t.isRunning())
return;
t.start();
@Override
public void actionPerformed(ActionEvent e)
ListIterator<Spaceship> iter = playingList.listIterator();
while (iter.hasNext())
Spaceship s = iter.next();
s.moveSpaceship();
repaint();
public void paintComponent(Graphics g)
super.paintComponent(g);
for (Spaceship s : playingList)
s.drawSpaceship(g);
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
Then update your main method to call it...
public static void main(String args)
EventQueue.invokeLater(new Runnable()
@Override
public void run()
SpaceGame game = new SpaceGame();
JFrame fr = new JFrame();
fr.setTitle("SPACE GAME");
// This is unadvisable :/
fr.setSize(990, 690);
fr.add(game);
game.playingList.add(new Spaceship(3, 0, 570));
game.playingList.add(new Spaceship(1, 250, 570));
game.playingList.add(new Spaceship(2, 500, 570));
JButton start = new JButton("START");
start.addActionListener(new ActionListener()
@Override
public void actionPerformed(java.awt.event.ActionEvent e)
game.start();
);
fr.add(start, BorderLayout.SOUTH);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
);
answered Nov 14 '18 at 22:38
MadProgrammerMadProgrammer
301k17154269
301k17154269
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53309623%2fstarting-animation-with-a-button-java-swing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Do not, ever, start a
Timer
inpaintComponent
, in fact, you should do NOTHING but paint the current state of the component in the paint methods. Instead, theTimer
should be started by some other action, independently of the paint process– MadProgrammer
Nov 14 '18 at 22:29
The other problem, as far as I can see is, the
Timer
and the button are using the sameactionPerformed
method, which doesn't make sense. Provide a method in yourSpaceGame
which can be called by the buttonsActionListener
– MadProgrammer
Nov 14 '18 at 22:31