I have a program which creates a window, loops through an array of colours and changes the window background to these colours.
I have used a pause method to allow me to pause each colour for a second before it loops onto the next.
Instead of pausing for a second, I want to be able to loop through the colours individually by pressing enter at each colour. I believe I need to make use of a scanner to do this, but I cannot get it to work myself.
Any help and an explanation would be really appreciated.
Here's the code that I've used to create the current pause method and loop the colours:
private void pause(long millisecs) {
long startTime = Calendar.getInstance().getTimeInMillis();
while(Calendar.getInstance().getTimeInMillis()-startTime<millisecs);
}
public void flashColour() {
Color [] rainbow = { Color.red,Color.orange,Color.yellow, Color.green,
Color.blue,Color.magenta,Color.black };
int index = 0;
System.out.println("Start");
pause(1000);
while(index < rainbow.length) {
getContentPane().setBackground(rainbow[index]);
pause(1000);
index++;
}
System.out.println("End");
}
I think you have misunderstood the purpose of a scanner. A scanner will parse primitive types and strings. What you're looking for is a keylistener. A keylistener will 'listen' for a specific key press (In this case enter) and run the appropriate code when that key is pressed.
For more information, see:
http://docs.oracle.com/javase/tutorial/uiswing/events/keylistener.html
Related
So I was making a simple game in Java + Processing where there were buttons and loops in draw(). Apparently the PApplet function mousePressed() doesn't work constantly if there is a loop, so I tried putting my own checkmouse() function to be checked during the loop. However, it still doesn't work. How do I make it so that I can run a game with while-loops and constantly check for mousePressed at the same time?
//draw() func
public void draw() {
for (int i = 0; i < 10000; i++) { //to simulate a while loop
//do something, like run some other functions that create the buttons
checkmouse();
}
}
//checkmouse function
public void checkmouse() {
if (mousePressed) {
System.out.println("x");
}
}
When I click the mouse in the processing window, it never shows "x" even though checkmouse() runs every time it loops, so theoretically it should be checking it pretty constantly while the loop runs.
Also could someone explain why this doesn't work?
boolean esc = false;
while (!esc) {
if (mousePressed) {
System.out.println("x");
esc = true;
}
}
The event variables (mousePressed, keyPressed, etc.) are updated between calls to the draw() function.
In other words: the mousePressed function will never change within a call to the draw() function. You need to let the draw() function complete and then be called again if you want the event variables to be updated.
Behind the scenes, this is because Processing is single-threaded. (This is by design, because multi-threaded UI programs are a nightmare.)
Taking a step back, you probably don't want to include a long loop inside your draw() function. Take advantage of the 60 FPS loop that's implemented by Processing instead.
I've been writing a method to switch two images. This method is called in a mouse drag-and-drop event and is followed by another method that lets images drop down a few positions (I'm talking about a sort of candy crush mechanism).
In my case, the transition in the second method starts before the switch is done, which is why you can barely see the switch.
What I'm looking for is a way to make the program wait until the first transition is finished before it steps into the next method. Thread.sleep() isn't working for me since it stops the switch animation as well, and I don't know how to use the transition.setOnFinished() properly within my switch method without causing an infinite loop.
This is part of my switch method:
public void animateSwitch(int xFirst, int yFirst, int xLast, int yLast) {
/.../
ParallelTransition allMovements = new ParallelTransition();
TranslateTransition tt = new TranslateTransition(Duration.millis(FALL_TIME_PER_ROW), getNodeFromGridPane(grdPane, xFirst, yFirst));
TranslateTransition tt2 = new TranslateTransition(Duration.millis(FALL_TIME_PER_ROW), getNodeFromGridPane(grdPane, xLast, yLast));
Image old = iv1.getImage();
iv1.setImage(iv2.getImage());
iv1.setTranslateX(iv2.getX());
iv1.setTranslateY(iv2.getY());
iv2.setImage(old);
iv2.setTranslateX(iv1.getX());
iv2.setTranslateY(iv1.getY());
if (xFirst == xLast) {
tt.toYProperty().set(0);
tt.toXProperty().set(tt.getFromX());
if (yFirst < yLast) {
tt.fromYProperty().set(rowHeight);
tt2.fromYProperty().set(-rowHeight);
}
else {
tt.fromYProperty().set(-rowHeight);
tt2.fromYProperty().set(rowHeight);
}
tt2.toYProperty().set(0);
tt2.toXProperty().set(tt2.getFromX());
}
else if (yFirst == yLast) {
tt.toXProperty().set(0);
tt.toYProperty().set(tt.getFromY());
if (xFirst < xLast) {
tt.fromXProperty().set(rowWidth);
tt2.fromXProperty().set(-rowWidth);
}
else {
tt.fromXProperty().set(-rowWidth);
tt2.fromXProperty().set(rowWidth);
}
tt2.toXProperty().set(0);
tt2.toYProperty().set(tt2.getFromY());
}
allMovements.getChildren().add(tt);
allMovements.getChildren().add(tt2);
allMovements.play();
}
Thanks in advance!
You will have to set the onFinished event handler using allMovements.setOnFinished(eventHandler); Here eventHandler is an object that implements the EventHandler interface.
EDIT:
I skipped past the part where you don't know how to prevent an infinite loop using this solution. You can use two different eventHandlers to do the different parts. The first calls the second when it finishes. The second doesn't need to call the first, so you will not get into a loop.
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());
}
}
I am using freeTTS to speak out some text, in the background i want a animated gif to keep playing
When i try this: as soon as the voice starts speaking, the image in background gets hanged even if i keep it in some other JFrame... and after the speech is completed it starts moving. I want it to run properly without pauses.
I am placing a animated gif in a label by importing it to my application and changing the icon to that image in label' properties.
Edit
Here is my code:
private void RandomjBActionPerformed(java.awt.event.ActionEvent evt) {
Voice voice;
voice = voiceManager.getVoice(VOICENAME);
voice.allocate();
voice.speak("Daksh");
}
I am actually using a lot of setVisible, setText, declaration of integers, calculating on them but i have removed them to simplify the code for you to understand. Still it gives the same problem if executed.
The button 'RandomjB' is clicked from another button by the following code:
final Timer timer = new Timer(zad, new ActionListener() {
int tick = 0;
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Success" + ++tick);
RandomjB.doClick();
final int col = Integer.parseInt(t3.getText());;
if (tick >= col) {
((Timer) e.getSource()).stop();
for(int g=0; g<col; g++){
jButton2.setVisible(true); // Check Button -> Visible
}
}
}
});
timer.setInitialDelay(0);
System.out.format("About to schedule task.%n");
timer.start();
System.out.format("Task scheduled.%n");
It is hard to tell without the code, I however assume that you loop the speech synthesis within the one and only Swing-Thread and therefore block all kind of window updates as long as the speech loop is in progress.
As stated by Shaun Wild: you need to use a second Thread for the speech loop.
You may want to do some research on Threads and Concurrency
These allow two things to operate simultaneously, this is just my assumption.
Assuming that you instantiate some kind of class for the FreeTTS you may want to do something like this
FreeTTSClass tts;
new Thread(new Runnable(){
public void run(){
tts = new FreeTTSClass();
}
}).start();
So I've been trying to write a simple game where a character is moving using the statement
character1.x+=0.1f*delta
where delta is the time (in milliseconds) between frames. This works well when I want to move it every frame, but I want to be able to move it a set distance (50 pixels, or a single tile in my game) at that speed. Using for() loops makes it move the sprite at maximum speed, so I can't do that. It has to work on a single keypress, so they don't have to hold the key down.
Of course, I've barely done anything ever in Java, so there's probably a really stupidly simple solution that I'm missing. For now, I can just change it to instantaneous movement, but it looks really jerky. Can someone help?
In this case, you might want to add a keyListener yo your component.
yourComponent.addKeyListener(new KeyAdapter () { // Possibly your Frame
#Override // Overrides the keyPressed event
public void keyPressed(KeyEvent e) {
if ( e == YOUR_KEY_CODE ) {
for( int var = 0; var < yourDistance; var ++ ){
yourSpriteComponent.x += 1;
try{
Thread.sleep(yourTimeInMilliSec);
} catch( Exception e ){
// Your catch block here
}
}
}
}
});
Where YOUR_KEY_CODE is the key that the user needs to be pressed in order to execute the for() loop. Key Codes can be found in javadoc