very new to java so please explain at a basic level. Attempting to make a snake game. In the process of typing up the code for the games background. Having an issue with the timer. The lines with issues marked with ***
package snake;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
public class Snake implements ActionListener {
public JFrame jframe;
public RenderPanel renderPanel;
public static Snake snake;
public Snake() {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
jframe = new JFrame("Snake");
jframe.setVisible(true);
jframe.setSize(800, 700);
jframe.setLocation(dim.width / 2 - jframe.getWidth() / 2, dim.height / 2 - jframe.getHeight() / 2);
jframe.add(renderPanel = new RenderPanel());
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main (String []args) {
snake = new Snake();
}
#Override
public void actionPerformed(ActionEvent arg0) {
renderPanel.repaint();
}
You cannot initialize a Timer with a int and a Snake object. That is not supported by the Timer class. Have a look at the Java Api. The Constructor Summary Shows you, which Constructors exist for the Timer class.
When you want to do something after a defined time do the following:
Timer timer = new Timer();
timer.schedule(new ReceiverTask(), 1000);
The 1000 is the delay in milliseconds untill the run method of the ReceiverTask will be called.
ReceiverTask should be a class extending TimeTask. For example:
class ReceiverTask extends TimerTask {
public void run() {
//update your Background her
}
}
Related
I made a digital clock. but its not working properly.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
public class DigitalClock extends JFrame implements ActionListener {
JLabel l1 = new JLabel();
Timer t;
public DigitalClock() {
super("Digital Clock");
l1.setFont( new Font("Verdana",Font.BOLD,11) );
l1.setHorizontalAlignment( JLabel.RIGHT);
l1.setVerticalAlignment( JLabel.BOTTOM);
t = new Timer(1000,this);
getContentPane().add(l1);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(110,100);
setVisible(true);
// call actionPerformed to get Time at the startup
actionPerformed(null);
}
public void actionPerformed(ActionEvent evt) {
l1.setText( new Date().toString().substring(11,19));
}
public static void main(String args[]) {
new DigitalClock();
}
} // end of class
I made a digital clock. but its not working properly.
Help me i can't find the problem..
plz help..
output is constant time
After creating Time obj just start timer
t.start();
in output time is constant not move. but i want continues time clock
Did you start the Timer?
If you start the Timer then you don't even need:
// actionPerformed(null);
I'm a Java beginner and I'm trying to build a simple stopwatch program that displays the time on a swing GUI. Making the stopwatch is easy, however I cannot find a way to make the GUI update every second and display the current time on the stopwatch. How can I do this?
Something along these lines should do it:
import java.awt.EventQueue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;
/** #see https://stackoverflow.com/a/11058263/230513 */
public class Clock {
private Timer timer = new Timer();
private JLabel timeLabel = new JLabel(" ", JLabel.CENTER);
public Clock() {
JFrame f = new JFrame("Seconds");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(timeLabel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
timer.schedule(new UpdateUITask(), 0, 1000);
}
private class UpdateUITask extends TimerTask {
int nSeconds = 0;
#Override
public void run() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
timeLabel.setText(String.valueOf(nSeconds++));
}
});
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final Clock clock = new Clock();
}
});
}
}
The timeLabel will always display the number of seconds the timer has been running.
You will need to correctly format it to display "hh:mm:ss"; one approach is shown here.
Create a container and add the label to it so that you can display it as part of the GUI.
Compare the result to this alternate using javax.swing.Timer.
A few days ago I posted a question about a program that caused text on screen to change color when the mousewheel was scrolled. It was unfortunately a badly put together question with too much code posted to be particularly useful.
I had several responses, one of which was from the user trashdog who posted something that fixed the problem (which can be found at the bottom of this page here: Window going blank during MouseWheelMotion event) , however having read the class descriptions of all the things I didn't know about in the program he posted and gone through its execution I don't understand why his achieves a different effect from mine.
His seems to log every mouse wheel movement where as mine only does the initial movement. Also several people commented that they couldn't replicate the effect of my program probably because it was so big.
Below is an extremely simplified version which still elicits the same effect (I hope).
Question: What is the fundamental difference between the two programs that fixes the screen going blank when the mouse wheel events are being processed?
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.LinkedList;
import javax.swing.JFrame;
public class WheelPrinter implements MouseWheelListener, Runnable {
JFrame frame;
LinkedList colorList;
int colorCount;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
WheelPrinter w = new WheelPrinter();
w.run();
}
public WheelPrinter() {
frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addMouseWheelListener(this);
frame.setVisible(true);
frame.setBackground(Color.WHITE);
colorList = new LinkedList();
colorList.add(Color.BLACK);
colorList.add(Color.BLUE);
colorList.add(Color.YELLOW);
colorList.add(Color.GREEN);
colorList.add(Color.PINK);
}
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
colorChange();
}
#Override
public void run() {
while(true) {
draw(frame.getGraphics());
try {
Thread.sleep(20);
} catch (Exception ex) {
}
}
}
public void draw(Graphics g) {
g.setColor(frame.getBackground());
g.fillRect(0,0,frame.getWidth(),frame.getHeight());
g.setFont(new Font("sansserif", Font.BOLD, 32));
g.setColor(frame.getForeground());
g.drawString("yes", 50, 50);
}
public void colorChange() {
colorCount++;
if (colorCount > 4) {
colorCount = 0;
}
frame.setForeground((Color) colorList.get(colorCount));
}
}
(Try spinning your mouse wheel really hard if you try running my code and it will become even more obvious)
while(true) { is endless loop, without break; f.e.
use Swing Timer instead of Runnable#Thread delayed by Thread.Sleep()
paint to the JPanel or JComponent, not directly to the JFrame
all painting to the Swing JComponent should be done in paintComponent()
more in the 2D Graphics tutorial
edit
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* based on example by #trashgod
*
* #see http://stackoverflow.com/a/10970892/230513
*/
public class ColorWheel extends JPanel {
private static final int N = 32;
private static final long serialVersionUID = 1L;
private final Queue<Color> clut = new LinkedList<Color>();
private final JLabel label = new JLabel();
public ColorWheel() {
for (int i = 0; i < N; i++) {
clut.add(Color.getHSBColor((float) i / N, 1, 1));
}
//clut.add(Color.BLACK);
//clut.add(Color.BLUE);
//clut.add(Color.YELLOW);
//clut.add(Color.GREEN);
//clut.add(Color.PINK);
label.setFont(label.getFont().deriveFont(36f));
label.setForeground(clut.peek());
label.setText("#see http://stackoverflow.com/a/10970892/230513");
setBackground(Color.white);
add(label);
label.addMouseWheelListener(new MouseAdapter() {
#Override
public void mouseWheelMoved(MouseWheelEvent e) {
label.setForeground(clut.peek());
clut.add(clut.remove());
}
});
}
#Override
public Dimension getPreferredSize() {
int w = SwingUtilities.computeStringWidth(label.getFontMetrics(
label.getFont()), label.getText());
return new Dimension(w + 20, 80);
}
private void display() {
JFrame f = new JFrame("ColorWheel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new ColorWheel().display();
}
});
}
}
The fundamental difference is that you are trying to interact with the Graphics object from the wrong thread and without knowing anything about the state the Graphics object is in at the time.
The generally correct way to interact with a Graphics object in Swing is by making a custom component which overrides the paintComponent(Graphics) method. You do your drawing while inside that method.
Your colorChange() method can tell your component to re-draw itself by calling repaint(), which will eventually lead to a call to paintComponent(Graphics) on the correct thread at the correct time.
See tutorial here
I would like to create a JButton that changes its text periodically after the first click. I'm not really familiar with Swing library. What would be a good starting point? May I update its text without an action?
Thank you.
for all periodical events in Swing I only suggest javax.swing.Timer
output by using Timer should be, for example
import java.awt.Color;
import java.awt.Dimension;
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.Timer;
public class CrazyButtonTimer {
private JFrame frame = new JFrame(" Crazy Button Timer");
private JButton b = new JButton("Crazy Colored Button");
private Random random;
public CrazyButtonTimer() {
b.setPreferredSize(new Dimension(250, 35));
frame.getContentPane().add(b);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
javax.swing.Timer timer = new Timer(500, new TimerListener());
timer.setInitialDelay(250);
timer.start();
}
private class TimerListener implements ActionListener {
private TimerListener() {
}
#Override
public void actionPerformed(final ActionEvent e) {
Color c = b.getForeground();
if (c == Color.red) {
b.setForeground(Color.blue);
} else {
b.setForeground(Color.red);
}
}
}
public static void main(final String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
CrazyButtonTimer crazyButtonTimer = new CrazyButtonTimer();
}
});
}
}
If you to change it on every fixed amount of time then you can use Swing Timer or Thread to do this. But for this you have to listen at least one action so that you can initialize and start it.
You can also use TimerTask class from java.util like follow:
java.util.TimerTask timerTask = new java.util.TimerTask() {
#Override
public void run() {
//change button text here using button.setText("newText"); method
}
};
java.util.Timer myTimer = new java.util.Timer();
myTimer.schedule(timerTask, 3 * 1000, 3* 1000); // This will start timer task after 3 seconds and repeat it on every 3 seconds.
I suggest you to create a timer (here you can find some doc)
Timer timer = new Timer(100,this);
Your class has to extend action listener ed implements the following method which allow you to change the text of your JButton(I called it ``button).
public void actionPerformed(ActionEvent e) {
if(e.getSource.equals(timer)){
button.setText("newText");
}
}
Luca
All the other answers fail to mention how to update non-periodically. If you need it to update irregularly, you can make a method in your GUI class called something like: updateButton(); and just call that every time you want it to change your text.
public void updateButton(String newText)
{
Button.setText(newText);
}
Just thought I'd add this in case someone wanted to set it irregularly.
If you want to change it periodically (e.g. every 5th second) you could create a new Thread which sets the text of the button to the desired value and repaints it (if necessary).
in what way can this be programmed.
a UI box that displays random number between min and max value for 2 seconds then shows blank for 2 seconds then shows another random numer for 2 seconds then shows blank for 10 seonds and then repeats the cycle infitely until form closed. Font of the text to be configurable.
any help at all will be appreciated.
UPDATE after feedback
this is my progress so far. simple jpanel. now how do i add random number and timer
import javax.swing.JFrame;
import javax.swing.JPanel;
public class RandomSlide {
public static void main(String[]args)
{
//Create a JPanel
JPanel panel=new JPanel();
//Create a JFrame that we will use to add the JPanel
JFrame frame=new JFrame("Create a JPanel");
//ADD JPanel INTO JFrame
frame.add(panel);
//Set default close operation for JFrame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set JFrame size to :
//WIDTH : 400 pixels
//HEIGHT : 400 pixels
frame.setSize(400,400);
//Make JFrame visible. So we can see it
frame.setVisible(true);
}
}
You have multiple languages in your tags, so I'm unsure what to repond with.
For java you'd make a JPanel with the appropriate UI elements and build a Timer instance to shoot off scheduled events every 2 seconds to update the value.
In VBA for Excel you'd have to do the same with a Form and Timer Control, however you may encounter more issues in Excel/VBA than in java.
Update 16/04/2010
You can actually sub-class the JPanel to clean up the code.
class RandomDialog extends JFrame
{
private Timer _timer;
private JPanel _container;
public RandomDialog()
{
_timer = new Timer();
_container = new JPanel();
// Etc...
}
}
From here you can instantiate your children and register an event on the timer to call a function on your class which generates the random number and displays it to a JLabel.
Then you can just call your dialog in your driver like so:
public static void main(string [] args)
{
RandomDialog rand = new RandomDialog();
rand.show();
}
Here is some code that will get you rolling.
Note that you could just extend a JLabel instead of JPanel. I used JPanel based on your question. Also, note that you may use timer.setDelay() API to change the timing. Also, you could stop the timer by a stop() call.
package answer;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class RandomPanel extends JPanel implements ActionListener {
private static final int TWO_SECONDS=2000;
private static final int MAX=99999;
private static final int MIN=0;
private Timer timer = new javax.swing.Timer(TWO_SECONDS, this);
private JLabel msgLabel;
Random generator = new Random();
public RandomPanel(Font f){
msgLabel = new JLabel();
msgLabel.setFont(f);
msgLabel.setText(rand());
add(msgLabel);
}
#Override
public void actionPerformed(ActionEvent e) {
msgLabel.setText(msgLabel.getText().equals("")?rand():"");
}
private String rand() {
//generate random beteween MIN & MAX
return Integer.toString((int) (MIN + Math.random() * ( MAX - MIN) + 0.5));
}
public void start(){
timer.start();
}
/**
* Rudimentary test
* #param args
*/
public static void main(String[] args) {
JFrame frame = new JFrame();
RandomPanel randomPanel = new RandomPanel(new Font("Serif", Font.BOLD, 50));
frame.getContentPane().add(randomPanel);
frame.setSize(400,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
randomPanel.start();
}
}