How to create sequence with thread.sleep in Java - java

I'm trying to create a simple sequence that basically consists on a JLabel's text being set to a value using an array and a for cycle. However it waits a certain time, before it changes.
My code looks something like this:
private String[] images = {"ball_00.bmp",
"ball_01.bmp",
"ball_02.bmp",
"ball_03.bmp",
"ball_04.bmp",
"ball_05.bmp",
"ball_06.bmp",
"ball_07.bmp",
"ball_08.bmp",
"ball_09.bmp",
"ball_10.bmp"};
public void runGif(){
for(int x = 0; x < this.images.length; x++) {
try {
System.out.println(images[x]);
this.lbl_image.setText(images[x]);
this.panel_CENTER.add(lbl_image);
this.lbl_image.setVisible(false);
this.lbl_image.setVisible(true);
System.out.println("I'm waiting");
Thread.sleep(CurrentSpeed);
System.out.println("I'm back");
}
catch(Exception e) {e.getStackTrace();}
System.out.println(x);
}
}
However I'm getting no output and the only thing I see on my JFrame is the label displaying "GIF", which is the default text that I set it to.
I don't know what migth be causing this issue, and would be very grateful if someone could help me.
Thank you for your attention in advance!

Related

ALT codes via keyPress in Java

So, to give a bit of context, I finally got tired of having to research for the ALT codes of certain symbols and sub/superscript numbers, and never getting it right, I suppose this mapping error have something to do with de keyboard version I'm using, but to be honest, I don't care, and to solve this problem I created a program in Java that will print all the alt codes going from Alt0000 to Alt9999 on a separate notepad window via keyPress but, I'm having problems on printing all of them, somehow it erases the text multiple times during the run, and after a while it starts printing nonsensical things.
As requested in a comment bellow, here's a print of the nonsensical things:
Nonsensical Things
And for adding more details, the program runs fine for the first 100-ish codes, them it erases some of the codes and run fine until de 6000-ish codes, which is where it starts printing only the pre texts that indicate the codes and don't breaking any lines, a further more down the line it also erases the progress, and keeps with de "nonsensical things" as I am calling it.
If someone could give me some tips on how to do/fix this I would very much appreciate.
Since I'm not an expert programmer I'm also accepting tips on how to improve my code.
Thanks. :)
This is my code:
package randomProjects;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.*;
public class SimulateKeyPress {
public static void main(String[] args) throws InterruptedException {
int[] keyEvents = {KeyEvent.VK_NUMPAD0,
KeyEvent.VK_NUMPAD1,
KeyEvent.VK_NUMPAD2,
KeyEvent.VK_NUMPAD3,
KeyEvent.VK_NUMPAD4,
KeyEvent.VK_NUMPAD5,
KeyEvent.VK_NUMPAD6,
KeyEvent.VK_NUMPAD7,
KeyEvent.VK_NUMPAD8,
KeyEvent.VK_NUMPAD9};
try {
Robot robot = new Robot();
// click on notepad window positioned at the rigth of the IDE
robot.mouseMove(1000,400);
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
// run trhought the thousand units
for(int um = 0; um <= 9; um++) {
// run trhought the hundreds
for(int c = 0; c <= 9; c++) {
// run trhought the dozens
for(int d = 0; d <= 9; d++) {
// run trhought the units
for(int u = 0; u <= 9; u++) {
// write the pressed keys
// alt+####
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_L);
robot.keyRelease(KeyEvent.VK_L);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_T);
robot.keyPress(KeyEvent.VK_ADD);
robot.keyRelease(KeyEvent.VK_ADD);
robot.keyPress(keyEvents[um]);
robot.keyRelease(keyEvents[um]);
robot.keyPress(keyEvents[c]);
robot.keyRelease(keyEvents[c]);
robot.keyPress(keyEvents[d]);
robot.keyRelease(keyEvents[d]);
robot.keyPress(keyEvents[u]);
robot.keyRelease(keyEvents[d]);
robot.keyPress(KeyEvent.VK_TAB);
// write the respective ALT CODE result
robot.keyPress(KeyEvent.VK_ALT);
robot.keyPress(keyEvents[um]);
robot.keyPress(keyEvents[c]);
robot.keyPress(keyEvents[d]);
robot.keyPress(keyEvents[u]);
robot.keyRelease(KeyEvent.VK_ALT);
robot.keyRelease(keyEvents[um]);
robot.keyRelease(keyEvents[c]);
robot.keyRelease(keyEvents[d]);
robot.keyRelease(keyEvents[u]);
// Break line
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
//Thread.sleep(100);
}
}
}
}
} catch (AWTException e) {
e.printStackTrace();
}
}
}
I've also found this related queries, but had no luck in finding an answer to my problem:
ALT-Codes in Java
How to detect Windows alt-code input without relying on keypress?
How to simulate keyboard presses in java?

memory game java gui

I'm trying to write a logic in memory game that when I click on cards and they are not a pair (different ID), program should swap them back after 1s. If they are same, then leave them as they are.
The problem is that when I first click and the card appears, after second clicking on another (different) card it doesn't appear and swap the first card after 1s. someone knows why the second card does not appear after clicking?
Btw when the pair is correct, everything works fine, here is my fragment of the code responsible for that logic in listener:
final int copy = i;
card2.addActionListener((e) -> {
card2.setIcon(new ImageIcon(icons[copy].getAbsolutePath()));
if(firstClick == null)
{
firstClick = (Card)e.getSource();
}
else
{
Card secondClick = (Card)e.getSource();
if(firstClick.getID() != secondClick.getID())
{
try
{
Thread.sleep(1000);
} catch (InterruptedException e1)
{
//e1.printStackTrace();
}
firstClick.setIcon(new ImageIcon(background.getAbsolutePath()));
secondClick.setIcon(new ImageIcon(background.getAbsolutePath()));
firstClick = null;
}
else
firstClick = null;
}
});
While method actionPerformed is executing, the GUI cannot react to mouse and keyboard events, so basically your code is "freezing" your GUI for one second. I believe that the class javax.swing.Timer is what you need and at first glance it looks like the duplicate question that MadProgrammer referred to may help you.

JavaFX Assigning action to all buttons in an array of arrays using for-loop

We have this warm up exercise where we're supposed to create this reallllly simple game which's UI is pretty much set up
.
I got the error "Local variable i defined in an enclosing scope must be final or effectively final".
I didn't understand it, so I googled it, but most of the problems are different.
While typing this question I found this in the stackoverflow suggestions:
Assigning an action to each button, in an array of buttons in JavaFX
But I simply don't understand. I'm learning programming/java from scratch. I hope JavaFX/GuI stuff isn't a hindrance?
The code below only includes my attempt to assign the actions. I separated it from the creation of the buttons for the time being to figure out what the problem is. The problem is only in the if and else conditions.
for(int i=0; i<=4; i++) {
for(int j=0; j<=4; j++) {
buttonGrid[i][j].setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
if (buttonGrid[i][j].getText() == "X") {
buttonGrid[i][j].setText("O");
} else {
buttonGrid[i][j].setText("X");
}
}
});
}
}
For now I just want the button's labels to change from X to O and from O to X as you click them. Btw. If I learn JavaFX and GUI, does it mean I HAVE to learn css? (Not that I don't want to, just.. not now)
If there is a need for the rest of the code to figure the problem:
http://textuploader.com/5b1kh
I'd also appreciate if someone could tell me how to do the Scenes in a more efficent way. (Btw, can I somehow lock the aspect ratio of the sides of all cells of a gridpane?)
I think that the answer in this question explains your problem very well and how to solve it Problems with local variable scope. How to solve it? You can not use i and j inside the Action handler.
Try this. [Notice that I've also changed the string comparison*]
for(int i=0; i<=4; i++) {
for(int j=0; j<=4; j++) {
final Button myButton = buttonGrid[i][j];
myButton.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
if ("X".equals(myButton.getText())) {
myButton.setText("O");
} else {
myButton.setText("X");
}
}
});
}
}
[*] How do I compare strings in Java?

I don't understand this java behaviour

I had a question about making a JButton flash colors ,like you would see when an answer was given in millionaire tv show. I got the answer there on how to do it properly but I also managed to "do it" in this way which raised some questions I couldn't answer totally.
As you see in the code bellow I am calling a
JOptionPane.showMessageDialog() after the JButton.setBackground and right before i stall the code using
do {
}while(time+i*100>System.currentTimeMillis());
Ignore the robot.keypress for the time. Lets get to the point. If i didn't use the JOptionPane before the code stalling , the ui would seem frozen and the button wouldn't repaint. But calling the JOptionPane.ShowMessageDialog() gives "time" to the button to repaint. Then the code is stalled normally and I achieve the sequential color repaint. I used the robot.keypress to close the Pane and achieve the effect desired.
My Questions: First, what happens when the JOptionPane is created that allows the button to repaint ? And secondly why the robot works only before the JOptionPane is called? I tried calling after the Pane was called like one would assume it should happen , but it wouldn't work in that case.
Extra: This didn't work in a mac it seems to only work for windows. Not quite sure.
public static void paintbutton(int bnr,boolean corr) {
long time;
try {
Robot robot = new Robot();
for (int i=5;i>1;i--){
b[bnr-1].setBackground(null);
// Simulate a key press
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
JOptionPane.showMessageDialog(null,"hi");
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
b[bnr-1].setBackground(i==1?(corr?Color.green:Color.red):Color.yellow);
// Simulate a key press
robot.keyPress(KeyEvent.VK_SPACE);
robot.keyRelease(KeyEvent.VK_SPACE);
JOptionPane.showMessageDialog(null,"hi");
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
}
} catch (AWTException e) {
System.err.println("error");
}
}
To avoid confusion as to the nature of this question!
The code in the state below doesn't work and I know it shouldn't. I am curious on how adding JOptionPane solves that.
public static void paintbutton(int bnr,boolean corr) {
long time;
for (int i=5;i>1;i--){
b[bnr-1].setBackground(null);
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
b[bnr-1].setBackground(i==1?(corr?Color.green:Color.red):Color.yellow);
time = System.currentTimeMillis();
do {
}while(time+i*100>System.currentTimeMillis());
}
}

JLabel Icon not updating with setIcon (or other redundancies)

Two different versions of code I'm using, as noted, the first one works fine, without any problems what so ever, the second one, the only thing that doesn't happen is the updating of the image (have verified through step debugging and debug printing to verify all values and conditionals by hand)
/* properly updates dice[] JLabel icons */
for (int i = 0; i < game.getToRoll(); i ++){
//sets rolled dice to actual values
dice[i].setIcon(dicePic[(game.getDice(i).getFaceValue())]);
}
/* loops properly, generates properly, does not update icons */
Die x = new Die();
int animate = 0;
while(animate < 10){
for (int i = 0; i < 6; i++ ){
x.roll();
if (i <= (game.getToRoll() -1))
dice[i].setIcon(dicePic[x.getFaceValue()]);
else
dice[i].setIcon(dicePic[0]);
}
panel[1].repaint();
panel[1].validate();
animate++;
try{
Thread.sleep(100);
}
catch(Exception e){
e.printStackTrace();
}
}
I've been looking around for some kind of idea of what it is that's causing the problem, and I've not run into anything other than that "sometimes repaint and validate will fix things that don't work."
As stated above, debug is giving me the greenlight on code flow working entirely as expected, just null image icons in the second example.
The problem is the Thread.sleep(100); The icon does change but you don't see the change because you blocked the UI thread.
So the rule is: never sleep the EventDispatchThread!
My advice is to use a Timer:
new javax.swing.Timer(200, new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
//do an icon change
}
}).start();

Categories

Resources