Using java timer in JFrame - java

when handset button pressed I want to green button color change red.After a certain time,again
I want to green button.I dont use timer class.Please help me.
For example my code
if (e.getSource() == handsetbutton) {
text1.setBackground(Color.RED);
// What l have to add here?
}

Run this example. I use a Swing Timer and set the delay to 4 seconds. When the button is pressed, it fires an action to change the color and start the timer. When the 4 seconds is up, the color changes back
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class GreenToRed extends JPanel {
private Color color = Color.RED; // global color object
static JButton button = new JButton("Change");
private Timer timer = null;
public GreenToRed(){
timer = new Timer(4000, new ActionListener(){ // Timer 4 seconds
public void actionPerformed(ActionEvent e) {
color = Color.RED; // after 4 seconds change back to red
repaint();
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
color = Color.GREEN; // change to green
repaint(); // repaint
timer.start(); // start timer
}
});
}
private static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new GreenToRed(), BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillOval(getWidth() / 2 - 50, getHeight() / 2 - 50, 100, 100);
}
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Related

Animation Constructor not working in Java GUI

Hello I am new to Java GUI I made a second.java which is as below:
package theproject;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay=50, totalFrames=8, currentFreames=1;
public second()
{
imageArray= new ImageIcon[totalFrames];
System.out.println(imageArray.length);
for(int i=0; i<imageArray.length;i++)
{
imageArray[i]=new ImageIcon(i+1+".png");
System.out.println(i+1);
}
animator= new Timer(delay, this);
animator.start();
}
public void paintComponent(Graphics g )
{
super.paintComponent(g);
if(currentFreames<8)
{
imageArray[currentFreames].paintIcon(this, g, 0, 0);
currentFreames++;
System.out.println(currentFreames);
}
else{
currentFreames=0;
}
}
#Override
public void actionPerformed(ActionEvent arg0) {
repaint();
}
}
And a Gui calling the constructor second and output is not showing . Can you please guide me what should I do and the gui is given below:
package theproject;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
textField = new JTextField();
textField.setBounds(10, 0, 261, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s= new second();
frame.add(s);
}
});
btnNewButton.setBounds(273, -1, 89, 23);
frame.getContentPane().add(btnNewButton);
}
}
The gui has to basically call the constructor and which will showcase the animation on the screen If someone what i am doing wrong or if something that has to be done please let me know .
First, don't update the state within the paintComponent method, paint can occur for a number of reasons at any time, mostly without your interaction. Painting should simple paint the current state. In your ActionListener, you should advance the frame and make decisions about what should occur (like resetting the frame value)
Second, you never actually add second to anything, so it will never be displayed.
Third, you don't override getPreferredSize in second, so the layout managers will have no idea what size the component should be and will simply be assigned 0x0, making it as good as invisible as makes no difference
Fourth, you're using null layouts. This is going to make you life impossibly hard. Swing has been designed and optimised around the use of layout managers, they do important work in deciding how best to deal with differences in font metrics across different rendering systems/pipelines, I highly recommend that you take the time to learn how to use them
Fifthly, paintComponent has no business been public, no one should ever call it directly
Example
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
public class Sav {
private JFrame frame;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Sav window = new Sav();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Sav() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
textField = new JTextField(20);
frame.getContentPane().add(textField, gbc);
JButton btnNewButton = new JButton("Submit");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
second s = new second();
frame.add(s, gbc);
frame.getContentPane().revalidate();
frame.pack();
frame.setLocationRelativeTo(null);
}
});
frame.getContentPane().add(btnNewButton, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class second extends JPanel implements ActionListener {
private Timer animator;
private ImageIcon imageArray[];
private int delay = 50, totalFrames = 8, currentFreames = 1;
public second() {
imageArray = new ImageIcon[totalFrames];
for (int i = 0; i < imageArray.length; i++) {
imageArray[i] = new ImageIcon(getImage(i));
}
animator = new Timer(delay, this);
animator.start();
}
protected Image getImage(int index) {
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
FontMetrics fm = g2d.getFontMetrics();
g2d.dispose();
String text = Integer.toString(index);
int height = fm.getHeight();
int width = fm.stringWidth(text);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setColor(getForeground());
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
return img;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imageArray[0].getIconWidth(), imageArray[1].getIconHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
imageArray[currentFreames].paintIcon(this, g, 0, 0);
}
#Override
public void actionPerformed(ActionEvent arg0) {
currentFreames++;
if (currentFreames >= imageArray.length) {
currentFreames = 0;
}
repaint();
}
}
}
Your code is also not working. It increment the values of image set but do not displays the images
Works just fine for me...
imageArray[i]=new ImageIcon(i+1+".png"); will not generate any errors if the image can't be loaded for some reason (and it will load the images in the background thread, which is just another issue).
Instead, I would recommend using ImageIO.read instead, which will throw a IOException if the image can't be read for some reason, which is infinitely more useful. See Reading/Loading an Image for more details

java Swing button action

I am new in java and i wanted to work on a simple paint program using java swing.
my simple paint program should draw a shape like triangle, circle and square whenever i clicked on buttons.
i managed to draw these shapes and print it without buttons but i can not do it using ActionListener?
As you see i have a single button at the moment, i want to draw the oval whenever this button is clicked.
This is the code that i am working on it so far:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class PaintProject extends JComponent implements ActionListener{
public static void main(String[] args) {
JFrame frame=new JFrame("NEW PAINT PROGRAME!");
JButton button1=new JButton("ADD");
PaintProject paint=new PaintProject();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(button1);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize(){
return new Dimension(500,500);
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
Could you please take following steps:
Step 1:
Insert button1.addActionListener(paint); just after PaintProject paint=new PaintProject(); in the main method of PaintProject.java
Step 2:
Remove the method named protected void paintComponent(Graphics g). Instead create following method:
private void drawOval(){
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0,0, 100, 100);
}
Step 3:
Call the above method as follows:
#Override
public void actionPerformed(ActionEvent e) {
drawOval();
}
EDIT:
Following example demonstrates how to draw two shapes when respective buttons are clicked:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class PaintProject extends JComponent implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame("NEW PAINT PROGRAME!");
JButton ovalButton = new JButton("Oval");
ovalButton.setActionCommand("Oval");
JButton rectangleButton = new JButton("Rectangle");
rectangleButton.setActionCommand("Rectangle");
PaintProject paint = new PaintProject();
ovalButton.addActionListener(paint);
rectangleButton.addActionListener(paint);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(paint);
frame.add(ovalButton);
frame.add(rectangleButton);
frame.pack();
frame.setVisible(true);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
private void drawOval() {
Graphics g = this.getGraphics();
g.setColor(Color.red);
g.fillOval(0, 0, 100, 100);
}
private void drawRectangle() {
Graphics g = this.getGraphics();
g.setColor(Color.green);
g.fillRect(150, 150, 100, 100);
}
#Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
if (command.equals("Oval")) {
drawOval();
} else if (command.equals("Rectangle")) {
drawRectangle();
}
}
}

Painting inside Swing Timer not working

I never worked with Timers before so my problem is probably stupid one really. My program draws a circle which is red and after random seconds the circle should change its color to green. I just made a swing timer as you can see below in the code. And it enters actionPerformed() method but it doesn't change color. Could you help me somehow fix my problem with changing colors?
My code:
package igrica;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ChangingCircle implements ActionListener{
JFrame frame;
Timer timer;
Random r;
public static void main(String[] args) {
ChangingCircle gui = new ChangingCircle();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.fillOval(100, 100, 100, 100);
Random r = new Random();
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.out.println("Timer out");
g.setColor(Color.green);
g.fillOval(100, 100, 100, 100);
}
});
timer.start();
}
}
}
There's quite the mess in your code. Try this:
public class ChangingCircle {
Color color = Color.RED;
MyPanel panel = new MyPanel();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ChangingCircle gui = new ChangingCircle();
gui.go();
});
}
public void go() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
Random r = new Random();
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.out.println("Timer");
color = Color.GREEN;
panel.repaint();
}
});
timer.setRepeats(false);
timer.start();
}
class MyPanel extends JPanel {
private int size = 100, loc = 100;
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillOval(loc, loc, size, size);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(size + loc, size + loc);
}
}
}
The idea is that the timer only changes the property of the shape to be drawn and then calls repaint() to reflect the change. The paintComponent is called whenever it is needed, even in quick succession and should return quickly.
Specific Notes:
Start Swing from the EDT.
Create and start the timer from outside of paintComponent since it is called many times and that will create and start many timers.
You should probably set the timer not to repeat.
Call super.paintComponent(g); as the first thing inside paintComponent.
You seem to have an ActionListener that does nothing.
General tips:
Use the #Override annotation when applicable.
Call pack() on the frame instead of setting its size manually and #Override the getPreferredSize method of the component you paint on. Return a meaningful size based on what you draw.
Use add(component, location) and not the other way around (deprecated).
Don't use fields when local variables will do (Random r for example).
Use uppercase constant names (Color.RED instead of Color.red).
Don't initiate a Timer from within a paintComponent method. This method should be for painting and painting only. Instead start the Timer in your constructor and within your Timer's actionPerromed and call repaint(), change the state of a field of the class, and use that information within the paintComponent use that field to draw any new information.
e.g.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ChangingCircle {
JFrame frame;
public static void main(String[] args) {
ChangingCircle gui = new ChangingCircle();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
class MyPanel extends JPanel {
private Random r = new Random();
private boolean draw = false;
public MyPanel() {
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
draw = true;
repaint();
}
});
timer.setRepeats(false);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (draw) {
g.setColor(Color.red);
g.fillOval(100, 100, 100, 100);
}
}
}
}
Also, don't forget to call the super's paintComponent method from within your override.
If you need to change colors, give the JPanel a Color field, say called color and change it's value from within the Timer, and then call repaint(). Again within paintComponent, use the value of that field to draw the oval with. Also in this situation, the Timer should repeat, so get rid of timer.setRepeats(false) in that situation.
The timer works asynchronously and paintComponent finishes before finishing the work of timer.

How to make JFrame paint only after I click button?

When I run the application the whole frame is painted black.
How can I make it so that it starts out clear then it gets painted when I press the button?
package card;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BdayCard extends JFrame {
JButton button1, button2;
JPanel panel;
BdayCard()
{
panel = new JPanel();
button1 = new JButton();
button1.addActionListener( new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
repaint();
}
});
panel.add(button1);
this.add(panel);
this.setTitle("It's Your Birthday!");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(600, 450);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
public void paint(Graphics g){
g.fillRect(0, 0, 600, 450);
}
public static void main(String[] args){
new BdayCard();
}
}
your problem with your blackscreen is because you paint at:
g.fillRect(0, 0, 600, 450);
you are using the default colour which is black
I tried your code and used this:
g.setColor(Color.WHITE);
this clears your screen and then use a boolean and set it true when your button is pressed:
public void actionPerformed(ActionEvent e)
{
button=true;
repaint();
}
then finally use:
if(button){/*do stuff here*/}
in the paint method

Resetting countdown timer not working + JDialog/JOptionPane in Java Swing game

I'm not that good with Java Swing and I'm trying to use a timer start the game with a delay in 3 seconds
But at the same time I want to show a dialog (also the game has to wait 3 seconds so the focus needs to be on the dialog)
So my dialog is as follow: got this sample code
So in my gameplay panel I do this:
public class GamePlayPanel extends JPanel implements ActionListener {
// attributes
private JOptionCountDownTimer countDownDialog;
public GamePlayPanel(MainWindow mainWindow) {
// initialization attributes
initLayoutPanel();
this.timer = new Timer(DELAY, this);
// Added a delay of 3 seconds so you can prepare to for the game
this.timer.setInitialDelay(3000);
resetTime();
}
public void startGame() {
this.gamePanel.requestFocus();
this.countDownDialog.startCountDown();
startTimer(); // this is my game timer to record the game time
}
public void restartGame() {
this.countDownDialog.resetCountDown();
startTimer();
this.gamePanel.requestFocus();
}
}
It works fine but if I restart the game the count down timer starts at 0 -> 2 seconds.
Also any better ideas on my class JOptionCountDownTimer? I tried to make it extend a JDialog class but I couldn't get it to work.
Try this out, see if it works for you. You can just grab the dialog class code. All you need to do is pass to it the parent frame, true for modality and seconds you want. You also may want to pretty it up. I'm just providing the functionality
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class CountDownTimer {
public CountDownTimer() {
final JFrame frame = new JFrame();
JButton button = new JButton("Open Dilaog");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
new CountDownTimerDialog(frame, true, 5);
}
});
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private class CountDownTimerDialog extends JDialog {
private int count;
public CountDownTimerDialog(JFrame parent, boolean modal, int seconds) {
super(parent, modal);
count = seconds;
final JLabel countLabel = new JLabel(String.valueOf(seconds), JLabel.CENTER);
countLabel.setFont(new Font("impact", Font.PLAIN, 36));
JLabel message = new JLabel("Wait to Start Game");
message.setFont(new Font("verdana", Font.BOLD, 20));
JPanel wrapper = new JPanel(new BorderLayout());
wrapper.setBorder(new EmptyBorder(10, 10, 10, 10));
wrapper.add(countLabel);
wrapper.add(message, BorderLayout.SOUTH);
add(wrapper);
Timer timer = new Timer(1000, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (count == -1) {
dispose();
} else {
countLabel.setText(String.valueOf(count));
count--;
}
}
});
timer.setInitialDelay(0);
timer.start();
pack();
setLocationRelativeTo(parent);
setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new CountDownTimer();
}
});
}
}

Categories