I am trying to make a simple timer, starting from 0 to whatever number.I want to interrup the timer when I press a button.
I've done this so far, I'n not interested about the button part yet.When I run, I don't get anything displayed.
import java.util.ArrayList;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/*lista clienti care asteapta
avem timer->creaza action event care il tratam in action performed--crestem timpul simu;larii cu 1 in action performed,apoi parcurgem lista de clienti care ast si verificam care clienti au timpul de arival = timpul simulatrii
--fiecare client e distribuit la una din cozi-for pt fiecare client. gasim coada cu timpul min de asteptare si il adaugam acolo--tot in action performed
daca timpul de servire a ajun l;a 0 clientul e scos din coada
*/
public class Magazin extends JFrame{
//protected ArrayList<Clienti> arrayClienti = new ArrayList<Clienti>();
public Magazin(){
}
class event implements ActionListener{
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
int count = 0;
count++;
TimeClass tc=new TimeClass(count);
Timer timer= new Timer(1000,tc);
timer.start();
//System.out.println(count+"sec:");
}
}
class TimeClass implements ActionListener{
int counter;
public TimeClass(int counter){
this.counter=counter;
}
public void actionPerformed(ActionEvent tc) {
counter++;
System.out.println("sec:"+counter);
}
}
}
In the Main class I have this:
public class Main {
public static void main(String args[]) {
new Magazin();
}
You need to create and display a top-level window for something to be visible, this means that since you're using a JFrame, somewhere in code you'll need a main method, and that somewhere in code that is called, you'll need:
Magazin magazin = new Magazin(); // create your JFrame
magazin.setVisible(true); // display it.
I don't see a main method anywhere or your setting a JFrame visible. You've got other problems as well, but this is the first step you'll need for creating a visible GUI.
Some other issues:
You've got an ArrayList of something, Clienti, that is never used.
You've got no component, such as a JLabel, displaying your Time.
Your Timer's ActionListener creates a new JFrame -- why would it want to do that?
Your Magazin class has an actionPerformed method -- why? It's not acting as an ActionListener and does not implement ActionListener.
You will want to study the Swing tutorials to better understand how to use these tools. You can find links to the Swing tutorials and to other Swing resources here: Swing Info
Related
Here is my main class
import javax.swing.Timer;
public class Test {
public static int k=9;
public static void main(String[] args) {
Timer t = new Timer(100, new Loop());
t.start();
}
}
And my class Loop which implements ActionListener
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Loop implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(Test.k==9){
System.out.println("Its's Working");
}
}
}
I don't know why? When I've fully what it need but it doesn't print "Its's Working" in the console
And one more question is that "Is this Timer class similar to Thread in java ?"
Thanks for your answer!
Your program exits immediately after stating the timer, giving it no chance to fire.
The AWT Event Dispatch Thread (EDT) will need to have started for some reason in order for the timer to stay alive.
Swing is supposed to be use from this thread. If you do so, it should work.
java.awt.EventQueue.invokeLater(() -> {
Timer t = new Timer(100, new Loop());
t.start();
});
To avoid indenting a lot of code , and to have a short main, I tend to create a method call go and use a method reference.
java.awt.EventQueue.invokeLater(Test::go);
private static void go() {
I am trying to make a simple program that will ask the user a question and then compare their answer with a stored correct answer. The problem seems to be that the main loop of the program is not running when I click the Ready JButton.
I tried changing the main method to another non-default name and adding a call to it in the actionPerformed() method, and it did seem to execute the loop at least once, but then led to not being able to close the applet without the task manager once I clicked the button. I don't know if that means it hit an endless loop or what.
I'm sure there is more to fix in this code besides this issue, but I cannot make any progress on that without clearing this up first. If there is a problem with the way I went about creating the GUI please let me know. I tried to base it off of an assignment I did that worked just fine, so I don't know whether or not that is the issue.
Any help provided is appreciated.
Here is the code:
import java.awt.*;
import javax.swing.*;
public class Langarden_App extends JApplet{
private int width = 800, height = 600;
private LangardenPanel langPanel;
public void init(){
langPanel = new LangardenPanel();
getContentPane().add(langPanel);
setSize(width, height);
}
}
And the class with the logic
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.*;
public class LangardenPanel extends JPanel{
private static JButton submit;
private static JButton ready = new JButton("Ready");
private static JLabel instruct;
private JTextField input = new JTextField(100);
private static String inString;
private static ArrayList<String> questions;
private static ArrayList<String> answers;
private static Random rand = new Random();
public LangardenPanel(){
questions = new ArrayList<String> (Arrays.asList("¿Qué es la palabra para 'inveirno' en ingles?", "¿Qué es la forma de 'yo' del verbo 'venir'?"));
answers = new ArrayList<String> (Arrays.asList("winter", "voy"));
instruct = new JLabel("Welcome to Langarden! Press Submit to begin. You have one minute and three attempts for each question.");
submit = new JButton("Submit");
this.setLayout(new BorderLayout());
add(BorderLayout.SOUTH, ready);
add(BorderLayout.NORTH, instruct);
add(BorderLayout.CENTER, input);
ready.addActionListener(new SubListener());
}
public static void main(String[] args){
try{
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e){
}
System.out.println("Setting text");
instruct.setText("Alright! Let's Go!");
try{
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e){
}
do{
System.out.println("Running loop");
int qnum = rand.nextInt(questions.size());
instruct.setText(questions.get(qnum));
for (int i=0; i<3; i++){
try {
TimeUnit.SECONDS.sleep(60);
} catch (InterruptedException e) {
}
if(checkAnswer(qnum, inString)){
instruct.setText("Correct!");
break;
} else {
instruct.setText("Try again...\n" + questions.get(qnum));
}
}
instruct.setText("The correct answer was " + answers.get(qnum));
try{
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e){
}
questions.remove(qnum);
answers.remove(qnum);
instruct.setText("Would you like to continue? Enter No and click Submit to exit.");
} while (!inString.equalsIgnoreCase("No") && questions.size() != 0);
instruct.setText("Congratulations, you have completed this module!");
}
private static boolean checkAnswer(int qnum, String inString) {
if (answers.get(qnum).equalsIgnoreCase(inString))
return true;
return false;
}
private class SubListener implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.println("Button Pressed!");
if(e.getSource() == ready){
add(BorderLayout.SOUTH, submit);
submit.addActionListener(new SubListener());
} else {
inString = input.getText();
}
}
}
}
Get rid of the main method. If this is running as an applet, then the program has no business having a main method.
Make all fields non-static. Yes all.
Get rid of the while-true loop. If this runs, this will squelch your Swing event thread rendering your GUI frozen and helpless. Use a Swing Timer instead as a "pseudo" loop. Please check out the Swing Timer Tutorial for more on this.
Any time you add a component to a container, you should call revalidate() and repaint() on that same container so that the container's layout managers can layout the new component, and so that the OS can repaint over any "dirty" pixels.
Rather than add a new JButton as you're doing, much better is to swap components using a CardLayout. The tutorial can be found here: CardLayout tutorial.
I am a novice coder, have a tiny bit of experience with C++ about 10 years ago and now learning java (it's been about 4-5 months). I have a little collaborative project going, and I've got some things to figure out.
Here's the code:
import java.awt.event.*;
import java.awt.*;
import javax.swing.JFrame;
import java.util.Scanner;
import java.util.Random;
public class Game extends JFrame {
GamePanel panel;
int[][] grid;
int size;
//...and some other variables
public Game(String title) {
super(title);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new GamePanel(grid,size);
this.add(panel);
Button button = new Button("WHAT");
button.setBounds(-100, -100, 70, 70);
this.add(button);
button.addKeyListener(new KeyHandler());
}
class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keycode = e.getKeyCode();
switch(keycode) {
//arrow keys input and stuff
}
if(checkForWin()) //checkForWin() returns a boolean value for win/loss
//won the game, thus end the thread here
if(checkForLoss()) // similar stuff as checkForLoss()
//lost the game, thus end the thread here
//...update the panel
panel.repaint();
}
}
public static void main(String [] args) {
Game me = new Game("GAME");
me.setVisible(true);
}
}
So that's pretty much how the whole game thing looks like.
And I have questions:
I am using a button and put it at a negative position to make it invisible and using it as a mean of KeyListener. Is there any other way to add a key listener? ex) to the panel or something?
I want to change it so that each "level" is a thread and make it like
public static void main(String [] args) {
int level = 1;
do {
GameThread gt = new GameThread("Game");
// run() will have the game constructor inside
gt.setLevel(level);
gt.start();
gt.join(); //wait until the game "level" is finished
if(won)
level++;
if(lost)
level = 1;
} while(!checkIfDonePlaying())
}
Somewhat like this. I'm having trouble making the thread continue to run until the game level is actually finished. How do I do that?
I want to add a JLabel to show the score on the frame. But when I do that, the score doesn't update when I repaint() it. How do I do that?
Thanks in advance!
A few things:
Yes, there is a way to add a KeyListener to the panel, and that's by using key bindings. For example:
javax.swing.InputMap im = panel.getInputMap(panel.WHEN_IN_FOCUSED_WINDOW);
javax.swing.ActionMap am = panel.getActionMap();
im.put(javax.swing.KeyStroke.getKeyStroke("pressed UP"), "up");
am.put("up", new javax.swing.AbstractAction() {
#Override
public void actionPerformed(ActionEvent ev) {
// handle up arrow key action here
}
});
Swing is an event-driven environment, so do-while loops should not be used. Instead, use a Swing timer that periodically checks if your level has been completed.
Since you're not doing any custom painting on your JLabel, you shouldn't be using repaint. Instead, use its setText method.
Here's a solution for your first issue:
panel.setFocusable(true);
panel.addKeyListener(this);
Then you should just be able to do the usual key listener methods. Be sure to implement KeyListener!
Solutions for your other issues on their way. (Actually take #TNT 's suggestion and use keybindings, I'm more comfortable with listeners but for games I usually use lwjgl or slick2d)
2.
I feel that running your programs levels may be a bit inefficient (that may just be me) I would suggest having one thread in a run method and have the following:
Public void reset(int level)
{
//reset all variables based on local variable level...
}
Call it like this:
Reset(++currentLevel)); //use ++ before currentLevel so it adds to it and then resets
And you could easily use switch cases to do some special stuff if you want
Switch(level){
case 1: //...
}
And so forth. (I'm typing on mobile sorry for weird caps)
I have a JFrame that has a button on it that starts a loop. The loop makes the robot click on my screen etc... On The JFrame, how come when the 'x' button is pressed, the program does not terminate? The button does absulotely nothing. I've removed all of the un-relevant code.
This controls the Robot:
package nova;
public class Run {
public static void main(String[] args) throws Exception {
while (true) {
// move
Thread.sleep(Number.random(350, 650));
// click
Control.getPos();
Thread.sleep(Number.random(120, 340));
// move
// click
Control.getPos();
Thread.sleep(Number.random(800, 1000));
// space bar
Thread.sleep(Number.random(11500, 12900));
// move
// click
Control.getPos();
Thread.sleep(Number.random(120, 340));
// move
// click
Control.getPos();
Thread.sleep(Number.random(800, 1000));
// space bar
Thread.sleep(Number.random(11500, 12900));
}
}
}
And this is the JFrame:
package nova;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class Main extends JFrame implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 1L;
public Main() {
/*
* JFrame.
*/
setSize(600, 600);// Size of JFrame
setVisible(true);// Sets if its visible.
/*
* JButton.
*/
JButton startButton = new JButton("Start");// The JButton name.
add(startButton);// Add the button to the JFrame.
startButton.addActionListener(this);// Reads the action.
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
onExit();
}
});
}
private void onExit() {
System.exit(0);
}
/*
* The main method.
*/
public static void main(String[] args) {
new Main();// Reads method main()
}
/*
* What the button does.
*/
public void actionPerformed(ActionEvent e) {
// does this when the button is pressed
try {
Run.main(null);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
I am completely confused on why the program is not terminating and closing. How this be resolved?
A Robot is not part of the GUI. It does not execute on the Event Dispatch Thread, so closing the GUI has no effect on it.
How this be resolved?
Add logic in your windowClosing(...) method to stop the Robot. So you will need to somehow restructure your code to get rid the while (true) loop.
Maybe you can create an ArrayList to keep track of all the events you want to generate. Then you can use a Timer to invoke each event. Then in the windowClosing() code you stop the Timer.
Why not just have:
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Become:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Consider the following code.
import edu.cmu.ri.createlab.terk.robot.finch.Finch;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class RobotControl extends JFrame {
public static void main (String args[]) {
RobotControl GUI = new RobotControl(); //GUI is the name of my object.
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.setSize(300,300);
GUI.setVisible(true);
GUI.setTitle("RobotControl");
}
private JButton foward;
public RobotControl() { //constructor
setLayout (new FlowLayout());
foward = new JButton("foward");
add(foward);
ActionListener e = new event();
foward.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerformed1(ActionEvent e){
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
}
Now consider the following code that would make my finch robot move foward for 10 seconds.
Finch myf = new Finch();
myf.setWheelVelocities(255, 255, 10000);
Now, my question is, would it be possible to execute the second piece of code as a result of clicking the foward button created on the GUI, from the first piece of code? If so how would i go about it. I have tried putting the finch code into the actionListener class but nothing happens. where am i going wrong. I need advice.
The short answer is, yes.
First, you need to maintain an instance of Finch as a instance variable...
public class RobotControl extends JFrame {
private Finch finch;
//...
}
You need to create an instance of Finch...
public RobotControl {
finch = new Finch();
}
Then in your ActionListener, you need to "communicate" with Finch
public void actionPerformed1(ActionEvent e){
myf.setWheelVelocities(255, 255, 10000);
}
The long answer, it's likely that you are going to have to issue multiple commands in sequence, the problem with this, is this process is likely to block the Event Dispatching Thread, preventing from responding to new incoming events and making it look like your application has "stopped"
While there are multiple ways you might alleviate this problem, if you don't need Finch to communicate with the UI (such as report status of motors or something), you could simply use a single threaded Executor of some kind and simply issue a sequence of commands via it.
If you need to provide feedback to the client UI, things become considerably more complicated...
Here is a sample code:
-------------------------
RobotControl.java
myrobot = new Finch();
foward = new JButton("foward");
add(foward);
forward.addActionListener(new ForwardButtonListener(myrobot));
-------------------------
ForwardButtonListener.java
public class ForwardButtonListener implements ActionListener {
Finch robotToControl;
public FowardButtonListener(Finch aRobot) {
robotToControl = aRobot;
}
public void actionPerformed (ActionEvent e) {
robotToControl.setWheelVelocities(255, 255, 10000);
}
}
-------------------------