really need your help.
Im tryng to do a delay in Canvas.
I have a path inside of a list to paint and i'm tryng to paint point by point inside of that list.
I'm using handler(and i tryied Timer also) but it is an inner class so i cant access the index(int i) that is used on for.
Where is what i'm tryng to do:
for (int i = 0; i < path.size(); i++) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
c.drawCircle(path.get(i).getxPosition(), path.get(i).getyPosition(), 3, painter);
}
}, 5 * 1000);
}
Thanks,
Stuart
Related
I try to design a GUI for a neural network I made recently. I am using the MNIST-dataset and want to display the handwritten digit using JPanels with the brightness-values written inside. By pressing the "train"-button the network gets trained and every new digit is displayed. However this happens in a for loop in the actionperformed method of the button and it seems that I can´t change the background of the labels or the text(at least it doesn´t display the changes) until the last one. I don´t know whether I´m right but it seems that only the last change gets displayed. That´s why my question is whether it is possible to "refresh" the JFrame inside the actionperformed method.
I already have tried revalidate(), invalidate() & validate(), SwingUtilities.updateComponentTreeUI(frame), but none of them worked.
Here is the relevant part of my code:
train.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < iMax; i++) {
...
digitRefresh(reader.getInputs()[i], (int) reader.getInputs()[i][0], 0);
}
}
});
.
public void digitRefresh(double[] pixelValue, int target, int result) {
for (int i = 0; i < 784; i++) {
double value = pixelValue[i + 1];
int brightness = (int) (value * 255);
l_digit[i].setText(String.valueOf(value));
l_digit[i].setBackground(new Color(brightness, brightness, brightness));
}
l_target.setText(String.valueOf(target));
l_result.setText(String.valueOf(result));
this.revalidate();
}
thank you for every awnser and sorry for my bad english.
The simplest thing to do is start a new thread.
#Override
public void actionPerformed(ActionEvent e) {
new Thread( ()->{
for (int i = 0; i < iMax; i++) {
...
final int fi = i;
EventQueue.invokeLater( ()->{
digitRefresh(reader.getInputs()[fi], (int) reader.getInputs()[fi][0], 0);
});
}).start();
}
Now all of the work is being done on a separate thread, then as the ... work finishes, digit refresh method called from the EDT. Notice the final int fi part. There are caveats about going back and forth on threads so it is good to look into better controls than just using thread.
Swing worker for example:
How do I use SwingWorker in Java?
I want to do different manipulations on Label inside Table in libGDX.
in my Table class I create a Label and scale\move\rotate it, I'm trying to call to this actions every time the actions is finishes so each time It will run on different string, but I got a crash because of calling to my self every time (i think).
a= new Label("", mLabelStyleAmount);
addActor(a); // in a Table class
action = Actions.run(new Runnable() {
#Override
public void run() {
lunchText(i);
}
});
private void lunchText (int i) {
a.setText(strings[i]);
ScaleToAction up = Actions.scaleBy(30, 20, 5)
a.setPosition(a.getWidth() * 0.2f, 50);
a.addAction(Actions.sequence(up, action));
i++;
}
Is this is the right way to call the same method each time I finished?
The exception you've got is being caused by infinite recurrence that being caused by adding action in method that is being fired by action :) It means that every time you add the action to your action you add action again and so on and so on...
Second thing is that when you are adding many action by using addAction method these actions are parallel not sequential!
The resolution is to use libGDX SequenceAction and to generate all action at the beginning. It should like:
SequenceAction sequence = Actions.sequence();
for(int i = 0; i < string.length; i++) {
sequence.addAction(Actions.run(new Runnable() {
#Override
public void run() {
a.setText(strings[i]);
a.setPosition(a.getWidth() * 0.2f, 50);
}
}, Actions.scaleBy(30, 20, 5)));
Another way is to check in render() method if a do not have any actions (what means that last actions is finished) and then add new action
//render()
if(a.getActions.size == 0)
addActionToA();
this year i started java at school, i've been asked to create a program that with 3 threads paints 30 random circles (10 for each thread).
I don't know how to work with the paintComponent very well but here's what i've done:
class MioPanel extends JPanel implements Runnable {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension dimCerchio1 = new Dimension(50, 50);
for(int i = 0; i < 10; i++) {
g.setColor(Color.black);
g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
}
/*for(int i = 0; i < 10; i++) {
g.setColor(Color.red);
g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
}
for(int i = 0; i < 10; i++) {
g.setColor(Color.blue);
g.drawOval((int) ((Math.random()*this.getWidth()) - (dimCerchio1.width)), (int) (Math.random()*this.getHeight() - (dimCerchio1.height )), dimCerchio1.width , dimCerchio1.height);
}*/
}
#Override
public void run() {
}
The run method is empty 'cause i don't actually know how i can work with both thread and paint
Here's the main:
public class Main {
public static void main(String[] args) {
MFrame mframe = new MFrame("Cerchi casuali");
Thread first = new Thread(new MioPanel());
/*Thread second = new Thread(new MioPanel());
Thread third = new Thread(new MioPanel());*/
}
}
I would appreciate any help, sorry for my english if something's wrong.
You don't try and put everything in one class.
Create a class that starts the Swing components on the SwingUtilities invokeLater method. Create the JFrame in this class.
Create a DrawingPanel class that extends JPanel. Add the DrawingPanel to the JFrame.
Create a Balls class that generates the x and y center and the radius of 10 balls. You can use the java.awt.Point class to hold the center. This class is a Java object. It does nothing but hold the center and radius of the balls.
Create a Drawing class that implements Runnable. Pass an instance of the Balls class to the Drawing class.
Create 3 instances of the Drawing class. Pass the 3 instances of the Drawing class to the DrawingPanel. Use the 3 instances in the paintComponent method. Do nothing but draw the balls in the paintComponent method.
Pass the instance of the DrawingPanel to the 3 instances of the Drawing class.
Start 3 threads with these 3 instances after the GUI is completed.
I create some node in javaFX. And I need to animate each node to translate between some point to some point in Pane with TranslateTransition. But I need to make each of that node move independently using different starting point. How to make this happen? I mean is there any something like Thread.pause in javaFX. I tried using the rough approach like in the code below:
public void mouseRespon(final double x, final double y){
animasi.pause();
thread = new Thread(
new Runnable() {
#Override
public void run() {
int i = 0;
while(threadStatus && i < allList.size()){
final int j = i;
Platform.runLater(new Runnable() {
#Override
public void run() {
DynamicsText text = allList.get(j);
TranslateTransition transition = new TranslateTransition();
transition.setNode(text);
transition.setFromX(text.getTranslateX());
transition.setFromY(text.getTranslateY());
text.setDestinyOffset(x, y);
text.initCurrentOffSet();
double destX = text.getPotitionX();
double destY = text.getPotitonY();
transition.setToX(destX);
transition.setToY(destY);
transition.setDuration(Duration.seconds(1));
transition.setAutoReverse(false);
transition.setCycleCount(1);
transition.play();
}
});
try{
Thread.sleep(25);
}catch(Exception e){}
i++;
}
}
});
thread.start();
animasi.play();
}
But I think that is not a good approach. And actually, when I run that snippet make a program crash (sometime) .
Create a ParallelTransition.
For each piece that you want to move, create a SequentialTransition, a PauseTransition, and the TranslateTransition. The PauseTransitions should be incrementally bigger for each piece, say 0, 25ms, 50ms, 75ms, etc. Add the PauseTransition and the TranslateTransition to the SequentialTransition. Add each SequentialTransition to the ParallelTransition.
Then play the ParallelTransition.
No need to create any Threads or mess with Platform.runLater(...).
I'm making a really simple snake game, and I have an object called Apple which I want to move to a random position every X seconds. So my question is, what is the easiest way to execute this code every X seconds?
apple.x = rg.nextInt(470);
apple.y = rg.nextInt(470);
Thanks.
Edit:
Well do have a timer already like this:
Timer t = new Timer(10,this);
t.start();
What it does is draw my graphic elements when the game is started, it runs this code:
#Override
public void actionPerformed(ActionEvent arg0) {
Graphics g = this.getGraphics();
Graphics e = this.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
e.fillRect(0, 0, this.getWidth(), this.getHeight());
ep.drawApple(e);
se.drawMe(g);
I would use an executor
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable toRun = new Runnable() {
public void run() {
System.out.println("your code...");
}
};
ScheduledFuture<?> handle = scheduler.scheduleAtFixedRate(toRun, 1, 1, TimeUnit.SECONDS);
Use a timer:
Timer timer = new Timer();
int begin = 1000; //timer starts after 1 second.
int timeinterval = 10 * 1000; //timer executes every 10 seconds.
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//This code is executed at every interval defined by timeinterval (eg 10 seconds)
//And starts after x milliseconds defined by begin.
}
},begin, timeinterval);
Documentation: Oracle documentation Timer
Simplest thing is to use sleep.
apple.x = rg.nextInt(470);
apple.y = rg.nextInt(470);
Thread.sleep(1000);
Run the above code in loop.
This will give you an approximate(may not be exact) one second delay.
You should have some sort of game loop which is responsible for processing the game. You can trigger code to be executed within this loop every x milliseconds like so:
while(gameLoopRunning) {
if((System.currentTimeMillis() - lastExecution) >= 1000) {
// Code to move apple goes here.
lastExecution = System.currentTimeMillis();
}
}
In this example, the condition in the if statement would evaluate to true every 1000 milliseconds.