Repainting/refreshing the JFrame - java
I have a "car" made with various objects using graphics g and I want to move it when a button is pressed. With that, I had no problem, but I have a problem with its path. When the car is moved, the old position is not cleared out.
Code of the car (to move when button is pressed):
static void gPostavi2(Graphics g){
Graphics2D g2d = (Graphics2D) g;
for(int x=500; x>89; x--){
//risanje
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In this class are only methods for moving things around, the class extends another that has non-moving objects, buttons, labels,... and the paintComponent method.
How can I clear the old position, every time the for statement goes around ?
EDIT: some more code down here. In the main class I have only this code:
public static void main(String[] args) {
staticnaGrafika.dodajGumbe();
}
In staticnaGrafika I have a ton of code, but this is the beginning of paintComponent:
public class staticnaGrafika extends JPanel{
staticnaGrafika(){
setBorder(BorderFactory.createLineBorder(Color.black));
}
public Dimension getPreferredSize(){
return new Dimension(1100, 740);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
//opticno stikalo
//preveri, ce ga plosca prekriva pri max. dvigu
g2d.setColor(Color.black);
g2d.fillOval(21, 148, 33, 33);
g2d.setColor(Color.yellow);
g2d.fillOval(22, 149, 31, 31);
g2d.setColor(Color.black);
g2d.fillRect(13, 159, 11, 1); //el. prikljucnice
g2d.fillRect(13, 166, 10, 1);
g2d.drawOval(7, 157, 5, 5);
g2d.drawOval(7, 164, 5, 5);
//naslon; spodnji omejevalec hoda bata
g2d.setColor(Color.black);
g2d.fillRect(5, 350, 13, 43);
g2d.fillRect(5, 380, 63, 13);
g2d.fillRect(262, 350, 408, 13);
g2d.fillRect(262, 350, 13, 43);
g2d.fillRect(212, 380, 63, 13);
there is just painting in here. Below I have another method, which adds buttons, actionListeners:
public static void dodajGumbe() {
final JFrame f = new JFrame();
//dvig, stop, spust
JButton dvig = new JButton("DVIGNI");
dvig.setBackground(Color.WHITE);
dvig.setFocusPainted(false);
dvig.setBounds(850,15,120,30);
JButton stop = new JButton("STOP");
stop.setBackground(Color.WHITE);
stop.setFocusPainted(false);
stop.setBounds(850,50,120,30);
JButton spust = new JButton("SPUSTI");
spust.setBackground(Color.WHITE);
spust.setFocusPainted(false);
spust.setBounds(850,85,120,30);
//komande bremen
JButton postavi2 = new JButton("nalozi breme");
postavi2.setBackground(Color.WHITE);
postavi2.setFocusPainted(false);
postavi2.setBounds(760,240,120,30);
JButton odvzemi2 = new JButton("razlozi breme");
odvzemi2.setBackground(Color.WHITE);
odvzemi2.setFocusPainted(false);
odvzemi2.setBounds(760,275,120,30);
JButton postavi5 = new JButton("nalozi breme");
postavi5.setBackground(Color.WHITE);
postavi5.setFocusPainted(false);
postavi5.setBounds(760,330,120,30);
JButton odvzemi5 = new JButton("razlozi breme");
odvzemi5.setBackground(Color.WHITE);
odvzemi5.setFocusPainted(false);
odvzemi5.setBounds(760,365,120,30);
Container gumbi = f.getContentPane();
spust.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gSpusti(f.getGraphics());
}});
dvig.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gDvigni(f.getGraphics());
}});
stop.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gStop(f.getGraphics());
}});
postavi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi2(f.getGraphics());
}});
odvzemi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi2(f.getGraphics());
}});
postavi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gPostavi5(f.getGraphics());
}});
odvzemi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dinamicnaGrafika.gOdvzemi5(f.getGraphics());
}});
gumbi.add(dvig);
gumbi.add(stop);
gumbi.add(spust);
gumbi.add(postavi2);
gumbi.add(odvzemi2);
gumbi.add(postavi5);
gumbi.add(odvzemi5);
f.getContentPane();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new staticnaGrafika());
f.pack();
f.setVisible(true);
}
You probably forgot to call
super.paintComponent(g);
in your paintComponent() method
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g); //Clear screen before redraw
//Your codes for painting..
}
You should never be calling sleep() on the UI thread. Instead, I highly recommend that you use javax.swing.Timer and an ActionListener. Something like:
void paintCar(Graphics2D g2d, int x) {
g2d.setColor(Color.blue);
g2d.fillRect(x+10, 351, 118, 23);
g2d.fillRect(x+12, 321, 30, 40);
g2d.fillRect(x+45, 330, 83, 20);
g2d.setColor(Color.black);
g2d.fillOval(x+19, 362, 20, 20);
g2d.fillOval(x+90, 362, 20, 20);
g2d.drawString("2t", x+70, 344);
}
int x = 0;
public MyConstructor() {
new Timer(5, this).start();
}
public void actionPerformed(ActionEvent ae) {
x++;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
paintCar(g2d, x);
}
It looks like the problem lies with your implementation. You could create a class for your Car objects and each car object keep track of their own coordinates.
For your case, if you are only moving the cars only when the button is clicked, you don't even need a Timer. Just update the car's position in the ActionListener for every button click.
OUTPUT:
class Car
{
private Color carColor;
private int x, y;
private int speed;
private static int carWidth = 100;
private static int carHeight = 30;
public Car(Color carColor, int speed){
this.carColor = carColor;
this.speed = speed;
x = 0;
y = 0;
}
public void moveTo(int x, int y){
this.x = x;
this.y = y;
}
public void draw(Graphics g){
//Draw a car object
g.setColor(carColor);
g.fillRect(x, y, carWidth, carHeight);
g.setColor(Color.BLACK);
//Draw Wheels
g.fillOval(x, y+carHeight, 30, 30);
g.fillOval(x+carWidth-30, y+carHeight, 30, 30);
}
public int getX(){return x;}
public int getY(){return y;}
public int getSpeed(){return speed;}
}
So when you move your car(s), just update their positions and that's all you need to do. Pay special attention to my paintComponent() method. You should keep that method simple and clutter free. It is only responsible for painting. All the movements of cars is done else where.
class DrawingSpace extends JPanel implements ActionListener{
Car c1, c2, c3;
public DrawingSpace(){
setPreferredSize(new Dimension(800, 400));
c1 = new Car(Color.RED, 5);
c2 = new Car(Color.GREEN, 8);
c3 = new Car(Color.BLUE, 10);
c1.moveTo(10, 50);
c2.moveTo(10, 180);
c3.moveTo(10, 280);
}
public void moveCars(){
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
c1.draw(g);
c2.draw(g);
c3.draw(g);
}
#Override
public void actionPerformed(ActionEvent e){
//Used for timer (to animate moving cars)
c1.moveTo((c1.getX()+c1.getSpeed()), c1.getY());
c2.moveTo(c2.getX()+c2.getSpeed(), c2.getY());
c3.moveTo(c3.getX()+c3.getSpeed(), c3.getY());
if(c1.getX() > 800)
c1.moveTo(0, c1.getY());
if(c2.getX() > 800)
c2.moveTo(0, c2.getY());
if(c3.getX() > 800)
c3.moveTo(0, c3.getY());
repaint();
}
}
For a task like this, it will be better and easier to use javax.swing.timer instead of implementing your own loop with Thread.sleep().
class MovingCars{
public static void main(String[] args){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
JFrame f = new JFrame("Moving Cars");
DrawingSpace ds = new DrawingSpace();
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(ds);
f.pack();
f.setLocationRelativeTo(null);
Timer t = new Timer(50, ds); //Delay of 50 milliseconds
t.start();
}
});
}
}
Related
Java Swing Set Location for Round Button
I have a question. I created the Round Button, the code references from someone else cause I'm beginner. I want to set the position for it, but It seem to be unsuccessful. I thought the error is from its contains. public final class ButtonDesigned extends JButton { public ButtonDesigned (String label) { super(label); Dimension size = getPreferredSize(); size.width = size.height = Math.max(size.width,size.height); setPreferredSize(size); setContentAreaFilled(false); } protected void paintComponent(Graphics g) { if (getModel().isArmed()) { g.setColor(Color.lightGray); } else { g.setColor(getBackground()); } g.fillOval(0, 0, getSize().width-1,getSize().height-1); super.paintComponent(g); } protected void paintBorder(Graphics g) { g.setColor(getForeground()); g.drawOval(0, 0, getSize().width-1, getSize().height-1); } Shape shape; public boolean contains(int x, int y) { if (shape == null || !shape.getBounds().equals(getBounds())) { shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight()); } return shape.contains(x, y); } public static void main(String[] args) { JButton button = new ButtonDesigned ("Click"); button.setBackground(Color.gray); button.setLocation(70, 70); button.addActionListener(new ActionListener() { #Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "you have clicked"); } }); enter code here JFrame frame = new JFrame(); frame.getContentPane().add(button); frame.getContentPane().setLayout(new FlowLayout()); frame.setSize(300, 300); frame.setVisible(true); } }
How to draw a circle on button press
I am trying to draw a circle when a button is pressed. public Buttons(Panel panel){ addStud = new JButton("+ Student"); addStud.setToolTipText("Add a student"); addStud.addActionListener(new AbstractAction() { #Override public void actionPerformed(ActionEvent e) { //draw circle here } }); This is my button in Button.java public void draw(Graphics g){ g.setColor(Color.BLUE); g.fillOval(200, 200, 400, 50); } This is what I am trying to call in Panel.java I have a public void paintComponent(Graphics g) but I don't want the circle to be drawn immediately. I have tried initializing Panel() and calling it with no success. What can I do here?
class MyPanel extends JPanel { Boolean drawBlue = false; public void drawBlueCircle( Boolean draw ) { drawBlue = draw; repaint(); } protected void paintComponent( Graphics g ) { if ( drawBlue ) { g.setColor(Color.BLUE); g.fillOval(200, 200, 400, 50); } } } Then in your button's actionPerformed method call myPanel.drawBlueCircle(true); where myPanel is the instance of MyPanel that you created.
Adding an actionlistener to a JButton
public class BelishaBeacon { public class Design extends JPanel { private boolean alternateColors = false; public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; //creating the shapes Rectangle box1 = new Rectangle(163, 180, 16, 45); Rectangle box2 = new Rectangle(163, 225, 16, 45); Rectangle box3 = new Rectangle(163, 270, 16, 45); Rectangle box4 = new Rectangle(163, 315, 16, 45); Rectangle box5 = new Rectangle(163, 360, 16, 45); Rectangle box6 = new Rectangle(163, 405, 16, 45); //drawing the shapes Ellipse2D.Double ball = new Ellipse2D.Double(a, b, 100, 100); g2.draw(ball); g2.draw(box1); g2.draw(box2); g2.draw(box3); g2.draw(box4); g2.draw(box5); g2.draw(box6); //coloring the shapes g2.setColor(Color.BLACK); g2.fill(box1); g2.fill(box3); g2.fill(box5); g2.setColor(Color.YELLOW); g2.fill(ball); if (alternateColors) { g2.setColor(Color.ORANGE); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } alternateColors = false; } public void alternateColors() { alternateColors = true; repaint(); } } public BelishaBeacon() { //frame JFrame frame = new JFrame(); frame.setSize(330, 550); frame.setTitle("Belisha Beacon"); frame.setLayout(new BorderLayout(0, 0)); final Design shapes = new Design(); JButton jbtFlash = new JButton("Flash"); jbtFlash.addActionListener( new ActionListener() { #Override public void actionPerformed(ActionEvent e) { Runnable r = new Runnable(){ #Override public void run(){ while(/* user stops / toggleButton state*/ true) { swapColors(); // some method using static boolean try{ Thread.sleep(500); }catch(Exception e){} } } private void swapColors() { boolean swapColors; Graphics g2; if (swapColors) { g2.setColor(Color.ORANGE); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } else { g2.setColor(Color.YELLOW); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } } }; Thread t = new Thread(r); t.start(); }}); JButton jbtSteady = new JButton("Steady"); jbtSteady.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { shapes.alternateColors(); } }); I have created an action listener for my jbutton steady and flash, I am just trying to created a method for swapColors for it to be initialised in the jbutton flash. The swapcolos method initially should alternate between the colours orange and grey
You wrote that you want it to flash every 0.5 seconds. To do so you need to start new thread for example jbtFlash.addActionListener( new ActionListener() { #Override public void actionPerformed(ActionEvent e) { Runnable r = new Runnable(){ #Override public void run(){ while(/* user stops / toggleButton state*/ true) { swapColors(); // some method using static boolean try{ Thread.sleep(500); }catch(Exception e){} } } }; Thread t = new Thread(r); t.start(); }});
if (alternateColors) { g2.setColor(Color.ORANGE); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } alternateColors = false; Should be: if (alternateColors) { g2.setColor(Color.ORANGE); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } else { g2.setColor(Color.YELLOW); g2.fill(new Ellipse2D.Double(a, b, 100, 100)); } AND public void alternateColors() { alternateColors = true; repaint(); } Should be: public void alternateColors() { //Flip boolean alternateColors alternateColors = !alternateColors; repaint(); }
ActionListener only responding once
I have created a basic Roulette wheel in Java, and I have a JButton with an ActionListener that spins the wheel. Once I have pressed the button once, it works as intended. The problem is: Once I press the JButton a second time, it no longer works. I will post my entire code, for anyone who wants to see exactly what I mean. Bonus Points: Bonus points to whoever can help me with the following things: Buttons don't appear until after you have either clicked them, or put the window in the background and brought it back up. For some reason, the spin ALWAYS lands on red. I have a method called randomSpin() which produces an int that is either 21 or 22, and that method DOES work, but for some reason when it's used in the spin method , it always spins 21 times. WheelBuilder import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; import java.lang.*; public class WheelBuilder extends JApplet{ public int total = 1000, score, Tbet = 100, last; public JLabel winning; public JButton spin, Abet, Sbet; RouletteWheel wheel = new RouletteWheel(); Graphics page; public Color color; public void init() { resize(540,600); spin = new JButton("SPIN!"); spin.addActionListener(new spinListener()); Container cp = getContentPane(); cp.setVisible(true); cp.setBackground((Color.GREEN).darker().darker()); Abet = new JButton("+BET+"); Abet.addActionListener(new aListener()); Sbet = new JButton("-BET-"); Sbet.addActionListener(new sListener()); cp.add(Sbet); cp.add(spin); cp.add(Abet); cp.setLayout(new FlowLayout(270, 5, 525)); } public void paint(Graphics page) { page.setColor((Color.GREEN).darker().darker()); page.fillRect(0, 0, 1000, 1000); setBackground((Color.GREEN).darker().darker()); wheel.paintWheel(page, wheel.getStatus()); page.setColor(Color.BLACK); page.drawString("TOTAL: "+total, 400, 50); page.drawString("Current Bet: "+Tbet, 400, 25); page.drawString("Last Spin:", 50, 25); page.setColor(Color.WHITE); page.fillOval(260, 75, 20, 20); page.fillRect(50, 35, 60, 25); page.setColor(color); page.drawString(""+last, 70, 52); } public class spinListener implements ActionListener { Timer tm = new Timer(100, this); int count = 0; int countEnd = randomSpin(); public void actionPerformed(ActionEvent e) { tm.start(); changeWheel(); if (wheel.getStatus()) { color = Color.RED; last = (int)(Math.random()*7)*2+1; } else { color = Color.BLACK; last = (int)(Math.random()*7)*2+2; } } public void changeWheel() { int countEnd = randomSpin(); if (count <= countEnd) { wheel.setStatus(!(wheel.getStatus())); repaint(); count++; } } public int randomSpin() { return ((int)(Math.random()*2)+21); } } public class aListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (Tbet <= total-50) { Tbet+=50; } last = 0; repaint(); } } public class sListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (Tbet > 50) { Tbet-=50; } last = 0; repaint(); } } } RouletteWheel import javax.swing.JApplet; import java.awt.*; public class RouletteWheel extends JApplet { public boolean status; public void paintWheel(Graphics page, boolean status) { if (status){ setBackground(Color.green); page.setColor(Color.orange.darker().darker()); page.fillOval(20, 20, 500, 500); page.setColor(Color.WHITE); page.drawOval(40, 40, 460, 460); page.setColor(Color.BLACK); int[] xback = {0+70,0+70,30+70,90+70,160+70,240+70,310+70,370+70,400+70,400+70,370+70,310+70,240+70,160+70,90+70,30+70}; int[] yback = {240+70,160+70,90+70,30+70,0+70,0+70,30+70,90+70,160+70,240+70,310+70,370+70,400+70,400+70,370+70,310+70}; page.fillPolygon(xback, yback, 16); int[] xvals = {0+70,0+70,200+70,30+70,90+70,200+70,160+70,240+70,200+70,310+70,370+70,200+70,400+70,400+70,200+70,370+70,310+70,200+70,240+70,160+70,200+70,90+70,30+70,200+70}; int[] yvals = {240+70,160+70,200+70,90+70,30+70,200+70,0+70,0+70,200+70,30+70,90+70,200+70,160+70,240+70,200+70,310+70,370+70,200+70,400+70,400+70,200+70,370+70,310+70,200+70}; page.setColor(Color.BLACK); page.setColor(Color.RED); page.fillPolygon(xvals, yvals, 24); page.setColor(Color.orange.darker().darker()); page.fillOval(140, 140, 260, 260); page.setColor(Color.lightGray); page.fillOval(220, 220, 100, 100); page.setColor(Color.GRAY); page.fillOval(240, 240, 60, 60); page.setColor(Color.DARK_GRAY); page.fillOval(260, 260, 20, 20); page.setColor(Color.WHITE); page.drawOval(100, 100, 340, 340); page.drawOval(110, 110, 320, 320); } if (!status) { setBackground(Color.green); page.setColor(Color.orange.darker().darker()); page.fillOval(20, 20, 500, 500); page.setColor(Color.WHITE); page.drawOval(40, 40, 460, 460); page.setColor(Color.RED); int[] xback = {0+70,0+70,30+70,90+70,160+70,240+70,310+70,370+70,400+70,400+70,370+70,310+70,240+70,160+70,90+70,30+70}; int[] yback = {240+70,160+70,90+70,30+70,0+70,0+70,30+70,90+70,160+70,240+70,310+70,370+70,400+70,400+70,370+70,310+70}; page.fillPolygon(xback, yback, 16); int[] xvals = {0+70,0+70,200+70,30+70,90+70,200+70,160+70,240+70,200+70,310+70,370+70,200+70,400+70,400+70,200+70,370+70,310+70,200+70,240+70,160+70,200+70,90+70,30+70,200+70}; int[] yvals = {240+70,160+70,200+70,90+70,30+70,200+70,0+70,0+70,200+70,30+70,90+70,200+70,160+70,240+70,200+70,310+70,370+70,200+70,400+70,400+70,200+70,370+70,310+70,200+70}; page.setColor(Color.BLACK); page.fillPolygon(xvals, yvals, 24); page.setColor(Color.orange.darker().darker()); page.fillOval(140, 140, 260, 260); page.setColor(Color.lightGray); page.fillOval(220, 220, 100, 100); page.setColor(Color.GRAY); page.fillOval(240, 240, 60, 60); page.setColor(Color.DARK_GRAY); page.fillOval(260, 260, 20, 20); page.setColor(Color.WHITE); page.drawOval(100, 100, 340, 340); page.drawOval(110, 110, 320, 320); } } public boolean getStatus() { return status; } public void setStatus(boolean s) { status = s; } }
Create basic animation
How can I create basic animation in Java? Currently i am trying to implement a basic animation program using swing in Java. But i am not getting whether my logic for program in correct or not. My program implements Runnable, ActionListener interfaces and also extends JApplet. I want to know that, is it necessary to differentiate start method of JApplet and Runnable? And if yes then why..? My program is basic balloon program, when I click on start button balloons start moving upward and comes to floor again. This will be continue till i press stop button. Here is my code. public class Balls extends JApplet implements Runnable{ private static final long serialVersionUID = 1L; JPanel btnPanel=new JPanel(); static boolean flag1=true; static boolean flag2=true; static boolean flag3=false; static int h; static int temp=10; Thread t=new Thread(this); JButton start; JButton stop; public void init() { try { SwingUtilities.invokeAndWait( new Runnable() { public void run() { makeGUI(); } }); } catch(Exception e) { JOptionPane.showMessageDialog(null,"Can't create GUI because of exception"); System.exit(0); } } private void makeGUI() { start=new JButton("start"); stop=new JButton("stop"); btnPanel.add(start); btnPanel.add(stop); add(btnPanel,BorderLayout.NORTH); } public void run() { while(true) { if(flag1) { repaint(); flag1=false; } else { try { wait(); flag3=true; } catch(InterruptedException e) { JOptionPane.showMessageDialog(null,"Error ocuured !!\n Exiting.."); System.exit(0); } } } } public void paintComponent(Graphics g) { super.paintComponent(g); int h=Integer.parseInt(getParameter("height")); if (flag1) { g.setColor(Color.RED); g.fillOval(10,h,50,50); g.setColor(Color.YELLOW); g.fillOval(50,h,20,20); g.setColor(Color.CYAN); g.fillOval(70,h,80,30); g.setColor(Color.BLUE); g.fillOval(120,h,50,60); g.setColor(Color.GRAY); g.fillOval(160,h,70,50); g.setColor(Color.GREEN); g.fillOval(200,h,80,80); g.setColor(Color.MAGENTA); g.fillOval(260,h,80,30); g.setColor(Color.DARK_GRAY); g.fillOval(320,h,60,40); g.setColor(Color.pink); g.fillOval(370,h,65,45); flag1=false; } else { g.setColor(Color.RED); g.fillOval(10,h-temp,50,50); g.setColor(Color.YELLOW); g.fillOval(50,h-temp,20,20); g.setColor(Color.CYAN); g.fillOval(70,h-temp,80,30); g.setColor(Color.BLUE); g.fillOval(120,355,50,60); g.setColor(Color.GRAY); g.fillOval(160,h-temp,70,50); g.setColor(Color.GREEN); g.fillOval(200,h-temp,80,80); g.setColor(Color.MAGENTA); g.fillOval(260,h-temp,80,30); g.setColor(Color.DARK_GRAY); g.fillOval(320,h-temp,60,40); g.setColor(Color.pink); g.fillOval(370,h-temp,65,45); if(flag2 && temp<=400) { temp+=10; if(temp==400) { flag2=false; } } else if(!flag2) { temp-=10; if(temp==10) { flag2=true; } } else { } } } public void start() { start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { t.start(); if(flag3) { notify(); } } }); stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { flag1=false; try { Thread.sleep(5000); } catch(InterruptedException e) { repaint(); t=null; } } }); } }
1) Use SwingTimer as recommended instead of your Runnable implementation. 2) Read about custom painting , and here 3) draw at the JPanel instead of on JFrame I have changed your code, examine it. I think, that it does what you want. import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.Timer; public class Balls extends JApplet { private static final long serialVersionUID = 1L; JPanel btnPanel = new JPanel(); static boolean flag1 = true; static boolean flag2 = true; static boolean flag3 = false; static int h; static int temp = 10; JButton start; JButton stop; private Timer timer; public void init() { SwingUtilities.invokeLater( new Runnable() { public void run() { makeGUI(); } }); } private void makeGUI() { timer = new Timer(10, new ActionListener() { #Override public void actionPerformed(ActionEvent arg0) { repaint(); } }); start = new JButton("start"); stop = new JButton("stop"); start.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { timer.start(); } }); stop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { timer.stop(); } }); btnPanel.add(start); btnPanel.add(stop); add(new MyPanel(), BorderLayout.CENTER); add(btnPanel, BorderLayout.NORTH); } class MyPanel extends JPanel{ public void paintComponent(Graphics g) { super.paintComponent(g); int h = Integer.parseInt(getParameter("height")); if (flag1) { g.setColor(Color.RED); g.fillOval(10, h, 50, 50); g.setColor(Color.YELLOW); g.fillOval(50, h, 20, 20); g.setColor(Color.CYAN); g.fillOval(70, h, 80, 30); g.setColor(Color.BLUE); g.fillOval(120, h, 50, 60); g.setColor(Color.GRAY); g.fillOval(160, h, 70, 50); g.setColor(Color.GREEN); g.fillOval(200, h, 80, 80); g.setColor(Color.MAGENTA); g.fillOval(260, h, 80, 30); g.setColor(Color.DARK_GRAY); g.fillOval(320, h, 60, 40); g.setColor(Color.pink); g.fillOval(370, h, 65, 45); flag1 = false; } else { g.setColor(Color.RED); g.fillOval(10, h - temp, 50, 50); g.setColor(Color.YELLOW); g.fillOval(50, h - temp, 20, 20); g.setColor(Color.CYAN); g.fillOval(70, h - temp, 80, 30); g.setColor(Color.BLUE); g.fillOval(120, 355, 50, 60); g.setColor(Color.GRAY); g.fillOval(160, h - temp, 70, 50); g.setColor(Color.GREEN); g.fillOval(200, h - temp, 80, 80); g.setColor(Color.MAGENTA); g.fillOval(260, h - temp, 80, 30); g.setColor(Color.DARK_GRAY); g.fillOval(320, h - temp, 60, 40); g.setColor(Color.pink); g.fillOval(370, h - temp, 65, 45); if (flag2 && temp <= 400) { temp += 10; if (temp == 400) { flag2 = false; } } else if (!flag2) { temp -= 10; if (temp == 10) { flag2 = true; } } else { } } } } }