bob9123
bob9123

Reputation: 745

Using Action Listeners for buttons

Code: Java Sphere class

 import javax.swing.*;
 import java.awt.*;
 import java.awt.geom.Ellipse2D;

public class Sphere extends JPanel {
private boolean flashinglights = false;
private int x = 168;
private int y = 75;


public void paintComponent(Graphics g) { 
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    if (flashinglights) { //This is the flash option. Here it should change between grey and orange
        g2.setColor(Color.ORANGE);
        Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
        g2.draw(ball);
        g2.fill(ball);
    } else {
        g2.setColor(Color.gray); //This should stay grey as it does now.
        Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
        g2.draw(ball);
        g2.fill(ball);
    }
}

public void chooseflashinglights(){ //Ignore these methods
    flashinglights = false;
}

public void choosesteady(){
    flashinglights = true;
}

public void flickerorange(int d) { y = y + d; }


public void flickergrey(int d) { y = y + d; }


public static void main(String[] args) {
    JFrame scFrame = new AnimationViewer();
    scFrame.setTitle("Circle");
    scFrame.setSize(400, 400);
    scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
    scFrame.setVisible(true);
}

}

Animation Viewer Class:

 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;


public class AnimationViewer extends JFrame {
JButton jbtFlash = new JButton("Flash");
JButton jbtSteady = new JButton("Steady");
JPanel bPanel = new JPanel();
Sphere sphPanel = new Sphere();
Timer timer;

public AnimationViewer() {
    this.add(bPanel, BorderLayout.SOUTH);
    bPanel.add(jbtFlash);
    bPanel.setLayout(new GridLayout(1,2));
    bPanel.add(jbtSteady);

    this.add(sphPanel, BorderLayout.CENTER);


    jbtSteady.addActionListener(new SteadyLights());
    jbtFlash.addActionListener(new FlashingLights());

    timer = new Timer(100, new TimerListener());
    timer.start();
}



class TimerListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        sphPanel.flickerorange(0);
        sphPanel.flickergrey(0);
        repaint();
    }
}
class FlashingLights implements ActionListener{
    public void actionPerformed(ActionEvent e){
        sphPanel.chooseflashinglights();
    }
}
class SteadyLights implements ActionListener{
    public void actionPerformed(ActionEvent e){
        sphPanel.choosesteady();
    }
}

}

So right now there is a sphere that appears on the screen. There are two buttons showed below. Flash and Steady. On the steady button it has to stay one colour (orange) which it does not.

Now on Flash it has to change from Orange to grey every 100 milli seconds.

I know it has to be something to do with Action listeners but how exactly do I implement this?

Upvotes: 0

Views: 84

Answers (2)

Daniel Kupčo
Daniel Kupčo

Reputation: 76

You have a lot of extra code. I would do it like this. Write flashing logic in paintComponent method. Then create just one timer. On tick call the paintComponent method for every 100ms. On flash button click start the timer, on steady button click stop the timer and call paintComponent once.

Sphere class:

public class Sphere extends JPanel {
private boolean flashinglights = false;
private int x = 168;
private int y = 75;
private Color[] colors = new Color[] {Color.ORANGE, Color.GRAY };
private int colorIndex = 0;

public void paintComponent(Graphics g) {
   super.paintComponent(g);
   Graphics2D g2 = (Graphics2D) g;
   if (!flashinglights) {
       g2.setColor(Color.ORANGE);
       Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
       g2.draw(ball);
       g2.fill(ball);
   } else {
       if(colorIndex > colors.length - 1)
           colorIndex = 0;

       g2.setColor(colors[colorIndex++]);
       Ellipse2D.Double ball = new Ellipse2D.Double(x, y, 50, 50);
       g2.draw(ball);
       g2.fill(ball);
   }
}

public void chooseflashinglights(){ //Ignore these methods
   flashinglights = true;
}

public void choosesteady(){
   flashinglights = false;
}

public static void main(String[] args) {
   JFrame scFrame = new AnimationViewer();
   scFrame.setTitle("Circle");
   scFrame.setSize(400, 400);
   scFrame.setDefaultCloseOperation((JFrame.EXIT_ON_CLOSE));
   scFrame.setVisible(true);
}

}

AnimationViewer class:

public class AnimationViewer extends JFrame {
JButton jbtFlash = new JButton("Flash");
JButton jbtSteady = new JButton("Steady");
JPanel bPanel = new JPanel();
Sphere sphPanel = new Sphere();
Timer timer;

public AnimationViewer() {
   this.add(bPanel, BorderLayout.SOUTH);
   bPanel.add(jbtFlash);
   bPanel.setLayout(new GridLayout(1,2));
   bPanel.add(jbtSteady);

   this.add(sphPanel, BorderLayout.CENTER);

   timer = new Timer(100, new TimerListener());
   jbtSteady.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            sphPanel.choosesteady();
            timer.stop();
            sphPanel.repaint();
        }
    });
   jbtFlash.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            sphPanel.chooseflashinglights();
            timer.start();
        }
    });

}

class TimerListener implements ActionListener {
   public void actionPerformed(ActionEvent e) {
       sphPanel.repaint();
   }
}

}

Upvotes: 2

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

I would do things a bit differently.

  • I'd have a field in my drawing JPanel class that indicates what color should be shown.
  • For instance, if there are only two colors that are swapped, I'd use a boolean field, and would swap it's value in my timer, and then base the color draw on its value.
  • The paintComponent method would use that field, the boolean, to decide which Color to use for g.setColor(...).
  • If many colors are drawn, the field could be a combination of an array of Color together with an int index into the array. Then I'd increment the index as needed, and use the index in paintComponent to decide which color to draw with.
  • I'd change that field in my Timer's ActionListener -- just a single call to change it, not your strange call to flicker orange and flicker gray.
  • I'd start the Timer with one button
  • I'd stop it with the other button. That's all the button's action listener would do, simply start or stop the timer.

Upvotes: 0

Related Questions