repaint() Jpanel not working after Event - multithreading
I am new learning repaint g programing methos, i am trying to make a simple Rock paper sccissors with grahpics an animations. i am using netbeans
Context: 2 java clases: PPT.java wich extend jpanel and a netbeans JFrame Form.
i added the PPT as a bean on the JFRame and it render nice the start animation (slide down and resize the images of rockpaper...)
After the animation i try diferents events like click on the bean and recall the PPT.motor method who is the one who Reposition the things and call reprint and sleep for make the animation.
After clicking and triggering the event, the execution runs smooth just before call method motor (almost last lane).
But when the programs have to go to motor by 2nd time it stay there for a while with no errors, not printing nothing in the windows, if you click more times it print images small then enormous with no animation.
I am almost sure that my problems come from not handling nice the Threads but who knows.
this is PPT.java
package ppt;
import com.sun.org.apache.bcel.internal.classfile.Constant;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import static java.lang.Thread.sleep;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class PPT extends JPanel{
//Variables de Imagen buffered para prevenir FLIKR
private BufferedImage piedra;
private BufferedImage tijera;
private BufferedImage papel;
//Game Variables
private int cpu;//CPU choice
private int j1;//J1 choice
private int totalCPU;//score
private int totalJ1;//score
private int ganaRonda;//0 ties, 1 j1 win -1 cpu win
//
private static GUI ventana;//Declaramos asi la variable ventana para poder acceder a sus Variables fuera del main.
//piedra= rock papel=paper XY=cordinate var TXTY= SizeVar
private int piedraX=240, piedraXCPU;//Cordenada X para renderizar la imagen
private int piedraY=280, piedraYCPU;//Coordenada Y para renderizar la imagen
private int piedraTX=242;//Tamaño de salida de la imagen en X 900
private int piedraTY=242;//Tanaño de salida de la imagen en Y 645
private int papelX=444, papelXCPU=-100;//Cordenada X para renderizar la imagen
private int papelY=248, papelYCPU=-100;//Coordenada Y para renderizar la imagen
private int papelTX=300;//Tamaño de salida de la imagen en X 600
private int papelTY=300;//Tanaño de salida de la imagen en Y 376
private int tijeraX=280, tijeraXCPU=-100;//Cordenada X para renderizar la imagen
private int tijeraY=240, tijeraYCPU=-100;//Coordenada Y para renderizar la imagen
private int tijeraTX=400;//Tamaño de salida de la imagen en X 210
private int tijeraTY=400;//Tanaño de salida de la imagen en Y 400
private Color color1=Color.RED;//Color de la caja izq 1
private Color color2=Color.BLUE;//Color de la caja izq 2
public static void main(String[] args) {
// TODO code application logic here
//INSTANCE OF JFRAMEFORM
ventana =new GUI("Piedra Papel Tijera");
ventana.setLocationRelativeTo(null);//Centra la ventana en el media
ventana.setVisible(true);//Hace visible la ventana
ventana.pPT1.motor(4);//pPT1 IS THIS CLASS INSTANCED FROM JFRAME AS BEAN
}
public PPT (){
//CONSTRUCTOR getting images
try {
this.piedra = ImageIO.read(getClass().getResource("piedra.png"));
this.papel = ImageIO.read(getClass().getResource("papel.png"));
this.tijera = ImageIO.read(getClass().getResource("tijeras.png"));
} catch (IOException ex) {
Logger.getLogger(PPT.class.getName()).log(Level.SEVERE, null, ex);
}
this.setSize(800, 700);//Establece el tamaño del jpanel a 800x700
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//THIS draw the Scores at the left of the screen
g.setFont(new Font("Arial",Font.BOLD,42));//establece la fuente
g.setColor(color1);//ColorRojo
g.fillRect(1, 350, 42, 84);//Dibuja el rectangulo Del Jugador
g.setColor(color2);//ColorAzul
g.fillRect(1, 264, 42, 84);//dibuja el rectangulo azul
g.drawString(Integer.toString(totalJ1) , 4, 420);//dibuja la puntuacion del J1 en azul
g.setColor(color1);//ColorRojo
g.drawString(Integer.toString(totalCPU) , 4, 313);//dibuja la puntuacion de la CPU en rojo
/THIS draw the images
g.drawImage(piedra, piedraX, piedraY,piedraTX,piedraTY,null);//pintamos la Image de la variable en la Posicion XY y con el tamaño TX TY
g.drawImage(papel, papelX, papelY,papelTX,papelTY,null);
g.drawImage(tijera, tijeraX, tijeraY,tijeraTX,tijeraTY,null);
}
public void cpuTira (){
//THIS generate RANDOM choose to cpu
cpu=(int) (Math.random() * (4 - 1)) + 1;
}
//This is the GameLoopHandler
public void motor (int num){
if (num==4){
//THIS RESET THE ORIGINAL VALUES OF vars FOR START AGAIN THE ANIMATION OF THE FIRST STAGE
piedraX=240;//Cordenada X para renderizar la imagen
piedraY=280;//Coordenada Y para renderizar la imagen
piedraTX=242;//Tamaño de salida de la imagen en X 900
piedraTY=242;//Tanaño de salida de la imagen en Y 645
papelX=444;//Cordenada X para renderizar la imagen
papelY=248;//Coordenada Y para renderizar la imagen
papelTX=300;//Tamaño de salida de la imagen en X 600
papelTY=300;//Tanaño de salida de la imagen en Y 376
tijeraX=280;//Cordenada X para renderizar la imagen
tijeraY=240;//Coordenada Y para renderizar la imagen
tijeraTX=400;//Tamaño de salida de la imagen en X 210
tijeraTY=400;//Tanaño de salida de la imagen en Y 400
//THIS MOVE THE IMAGES down until near the bottom and resize them
while (piedraY<500){
if (piedraY>400){
piedraTX--;
piedraTY--;
papelTX--;
papelTY--;
tijeraTX-=2;
tijeraTY-=2;
}
if(tijeraY>359)
tijeraX++;
if(papelY>385)
papelX++;
piedraY++;
tijeraY++;
papelY++;
repaint();
try {//CUANTO MAS TIEMPO DE SLEEP MAS LENTA VA LA ANIMACION (FPS)
Thread.sleep(18);
} catch (InterruptedException ex) {
Logger.getLogger(PPT.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
//THIS METHOD IS called by the event in JFRAME FORM
public void controlJuego(int jugador1){
j1=jugador1;//set the choice of j1
cpuTira();//set the choice of CPU
//Calculate win 1 rock, 2paper,3 scissors
switch(j1){
case 1:
if(cpu==1)
ganaRonda=0;
if(cpu==2)
ganaRonda=-1;
if(cpu==3)
ganaRonda=1;
break;
case 2:
if(cpu==1)
ganaRonda=1;
if(cpu==2)
ganaRonda=0;
if(cpu==3)
ganaRonda=-1;
break;
case 3:
if(cpu==1)
ganaRonda=-1;
if(cpu==2)
ganaRonda=1;
if(cpu==3)
ganaRonda=0;
}
//Animation of "Fight" Currently i just want to repeat the start animation
System.out.println("hellow");//it printed hellow quicly
motor(4);//4 = intro animation
System.out.println(Integer.toString(ganaRonda));//it printed the variable after half minut and dindt redender nothing.
}
}
The JFrame Form have the default netbeans code, and the bean deployed.
So the thread mess can come cause i call the eventClick in JFrame and then explode.
Thanks for helping, sorry about the wallcode i just want to understand the thing.
Solution:
i Started a new NOT netbeans GUI base project folowing this code https://www.youtube.com/watch?v=_ix-jCzG53A
and modifyng the Ant class to my own game class.
Also for the animations runing smoothly update i have to create a new Thread code wich have to run on the EDT with a timer repting it each 10ms or delay you want.
(Like this but setting setRepetas to true and ) 10ms instead of 300
Timer timer = new Timer(10, new ActionListener(){
https://stackoverflow.com/a/22968559/4748324
Final code like this
int delay=10;
//Creamos un timer que se repetira para actualizar la posicion de los elementos adecuadamente en el EDT
Timer piedraJtimer = new Timer(delay, new ActionListener(){
/*So the Timer object will create a new thread, delay for 300 milliseconds, and then call the 'actionPerformed' method.
This will happen on the Timer's thread. It's not recommended to change UI elements from any thread except for the EDT,
so we use the invokeLater method which causes swing to run the runnable on the EDT itself - so back on the original thread.*/
#Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// runs code on the EDT to edit UI elements (recommended way)
if (piedraY!=280){//if StoneY is not in 280 make animation
if (piedraY<444){
piedraX++;
}
piedraY--;
}else//if Stone Y is in 280 y and the Cpu Stone or Cpu paper or Cpu sicssors are in place redy to roll out
if(piedraYCPU==404 || tijeraYCPU==400 || papelYCPU==400)
piedraX-=4;//Roll out sliding to left
if(piedraX<=0){//if Stone rolled out, set controls On and Stop the recursive timer
puedeAccionar = true;
piedraJtimer.stop();//Canceling the timer repeats.
}
}
});
}
});
The repaint(); method is caling in gameloop each delay miliseconds
Related
how do you pass a parameter from post method to decorator?
I'm working a python django and django rest framework + swagger (drf-yasg) project. I need a dynamic decorator. how do you pass a parameter(named in this case "essource") of post method to decorator? def xxx(esSource): source = {} if esSource == 1: source = { 'field_1': openapi.Schema(type=openapi.TYPE_INTEGER) } else: source = { 'field_44': openapi.Schema(type=openapi.TYPE_INTEGER) } properties = { 'type_operator': openapi.Schema(type=openapi.TYPE_INTEGER,description="L'operatore di insieme AND(0) OR(1)"), 'column_to_hide': openapi.Schema(type=openapi.TYPE_STRING,description="L'elenco di colonne da nascondere separato da virgola") } return properties.update(source) class ShowResultsView(views.APIView): #swagger_auto_schema( operation_description="La prima pagina di risultati della ricerca", request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['type_operator','column_to_hide'], properties=xxx(essource) ), ) def post(self,request,essource,page): resp = {} resp["status"] = 0 resp["data"] = {} resp["message"] = "I risultati della ricerca" return Response(resp,status=status.HTTP_200_OK) I get an error in this line code: properties=xxx(essource)
Botman Telegram
they could help me I do not know how to put buttons in telegram, only in facebook messenger, where the error can be ? $botman->hears('1', function ($bot) { $bot->reply("• Android versión 4.4.2 (KitKat) o superior • Espacio en memoria de almacenamiento • Memoria RAM superior a 1 GB • Duración de batería superior a 12 horas de uso continuo • Conexión a red celular 3G o superior • Conexión a Internet"); $bot->reply('¿ Algo más en lo que pueda ayudarte ?') ->addButton(Button::create('Tell a joke') ) ->addButton(Button::create('Give me a fancy quote') ) });
This is solved using the classes of app / Conversations.php <?php namespace App\Conversations; use Illuminate\Foundation\Inspiring; use BotMan\BotMan\Messages\Incoming\Answer; use BotMan\BotMan\Messages\Outgoing\Question; use BotMan\BotMan\Messages\Outgoing\Actions\Button; use BotMan\BotMan\Messages\Conversations\Conversation; class ExampleConversation extends Conversation { /** * First question */ public function askReason() { $question = Question::create("Huh - you woke me up. What do you need?") ->fallback('Unable to ask question') ->callbackId('ask_reason') ->addButtons([ Button::create('Tell a joke')->value('joke'), Button::create('Give me a fancy quote')->value('quote'), ]); return $this->ask($question, function (Answer $answer) { if ($answer->isInteractiveMessageReply()) { if ($answer->getValue() === 'joke') { $joke = json_decode(file_get_contents('http://api.icndb.com/jokes/random')); $this->say($joke->value->joke); } else { $this->say(Inspiring::quote()); } } }); } //clases dinamicas, cambiar estructura de base de datos :v /** * Start the conversation */ public function run() { $this->askReason(); } } and in your botman.php : $botman->hears('/start', function (BotMan $bot) { $bot->startConversation(new ExampleConversation()); });
processing - record and show video in the processing sketch
I have a webcam feed in my processing sketch and i can record and save the video. What i wanna accomplish is that when i go to the next case (drawScreenOne) that the video i just recorded will show up on the canvas. The problem that i have now, is that when i save the video, with the video export library from com.hamoid, it gets saved in the same folder as my sketch, but to play a movie it needs to be in the data folder. So i can't play the movies without it manually moving to the data folder. Can you do that from within processing? And how can i load up the videos that i just created in a case before? Do i need to use an array for that? I can play the movies when i manually move it to the data folder but i want processing to handle that. this is the code i have so far: import com.hamoid.*; import processing.video.*; import ddf.minim.*; Minim minim; AudioInput in; AudioRecorder recorder; Movie myMovie; Movie myMovie1; int currentScreen; VideoExport videoExport; boolean recording = false; Capture theCap; Capture cam; int i = 0; int countname; //change the name int name = 000000; //set the number in key's' function // change the file name void newFile() { countname =( name + 1); recorder = minim.createRecorder(in, "file/Sound" + countname + ".wav", true); // println("file/" + countname + ".wav"); } void setup() { size(500,500); frameRate(30); noStroke(); smooth(); myMovie = new Movie(this, "video0.mp4"); myMovie.loop(); myMovie1 = new Movie(this, "video1.mp4"); myMovie1.loop(); String[] cameras = Capture.list(); if (cameras.length == 0) { println("There are no cameras available for capture."); exit(); } else { println("Available cameras:"); for (int i = 0; i < cameras.length; i++) { println(cameras[i]); } // The camera can be initialized directly using an // element from the array returned by list(): //cam = new Capture(this, cameras[3]); //built in mac cam "isight" cam = new Capture(this, 1280, 960, "USB-camera"); //externe camera Lex, linker USB cam.start(); } println("Druk op R om geluid en video op te nemen.Druk nog een keer op R om het opnemen te stoppen en druk op S om het op te slaan Druk vervolgens op Z om verder te gaan."); videoExport = new VideoExport(this, "video" + i + ".mp4"); minim = new Minim(this); // get a stereo line-in: sample buffer length of 2048 // default sample rate is 44100, default bit depth is 16 in = minim.getLineIn(Minim.STEREO, 2048); // create a recorder that will record from the input to the filename specified, using buffered recording // buffered recording means that all captured audio will be written into a sample buffer // then when save() is called, the contents of the buffer will actually be written to a file // the file will be located in the sketch's root folder. newFile();//go to change file name textFont(createFont("SanSerif", 12)); } void draw() { switch(currentScreen){ case 0: drawScreenZero(); break; //camera case 1: drawScreenOne(); break; //1 video case 2: drawScreenZero(); break; //camera case 3: drawScreenTwo(); break; // 2 video's case 4: drawScreenZero(); break; //camera case 5: drawScreenThree(); break; //3 video's case 6: drawScreenZero(); break; //camera case 7: drawScreenFour(); break; //4 video's default: background(0); break; } } void mousePressed() { currentScreen++; if (currentScreen > 2) { currentScreen = 0; } } void drawScreenZero() { println("drawScreenZero camera"); if (cam.available() == true) { cam.read(); } image(cam, 0,0,width, height); // The following does the same, and is faster when just drawing the image // without any additional resizing, transformations, or tint. //set(0, 0, cam); if (recording) { videoExport.saveFrame(); } for(int i = 0; i < in.bufferSize() - 1; i++) { line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50); line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50); } if ( recorder.isRecording() ) { text("Aan het opnemen...", 5, 15); text("Druk op R als je klaar bent met opnemen en druk op S om het op te slaan.", 5, 30); } else { text("Gestopt met opnemen. Druk op R om op te nemen, druk op S om op te slaan.", 5, 15); } } void drawScreenOne() { background(0,255,0); //fill(0); //rect(250,40,250,400); println("drawScreenOne 1 video"); image(myMovie, 0,0, (width/2),(height/2)); } void drawScreenTwo(){ background(0,0,255); println("drawScreenTwo 2 videos"); //triangle(150,100,150,400,450,250); image(myMovie, 0,0, (width/2),(height/2)); image(myMovie1, (width/2),(height/2),(width/2),(height/2)); } void drawScreenThree(){ //fill(0); //rect(250,40,250,400); background(255,0,0); println("drawScreenThree 3 videos"); image(myMovie, 0,0, (width/2),(height/2)); image(myMovie1, (width/2),(height/2),(width/2),(height/2)); image(myMovie, (width/2),0, (width/2),(height/2)); } void drawScreenFour(){ //triangle(150,100,150,400,450,250); background(0,0,255); println("drawScreenFour 4 videos"); image(myMovie, 0,0, (width/2),(height/2)); image(myMovie1, (width/2),(height/2),(width/2),(height/2)); image(myMovie, (width/2),0, (width/2),(height/2)); image(myMovie1, 0,(height/2),(width/2),(height/2)); } void keyPressed() { if (key == 'r' || key == 'R') { recording = !recording; println("Recording is " + (recording ? "ON" : "OFF")); } else if (key == 's' || key == 's') { i++; videoExport = new VideoExport(this, "video" + i + ".mp4"); currentScreen++; if (currentScreen > 7) { currentScreen = 0; } } } void movieEvent(Movie m) { m.read(); } void keyReleased() { if ( key == 'r' ) { // to indicate that you want to start or stop capturing audio data, you must call // beginRecord() and endRecord() on the AudioRecorder object. You can start and stop // as many times as you like, the audio data will be appended to the end of the buffer // (in the case of buffered recording) or to the end of the file (in the case of streamed recording). if ( recorder.isRecording() ) { recorder.endRecord(); } else { /*#######################################*/ newFile(); /*#######################################*/ recorder.beginRecord(); } } if ( key == 's' ) { // we've filled the file out buffer, // now write it to the file we specified in createRecorder // in the case of buffered recording, if the buffer is large, // this will appear to freeze the sketch for sometime // in the case of streamed recording, // it will not freeze as the data is already in the file and all that is being done // is closing the file. // the method returns the recorded audio as an AudioRecording, // see the example AudioRecorder >> RecordAndPlayback for more about that name++; //change the file name, everytime +1 recorder.save(); println("Done saving."); println(name);//check the name } } void stop() { // always close Minim audio classes when you are done with them in.close(); minim.stop(); super.stop(); }
Can you do that from within processing? Sure. Just google something like "Java move file" and I'm sure you'll find a ton of results. Or you could just save the video to the data directory in the first place. I've never used the VideoExport class so this is just a guess, but I'd imagine that this would put the video in the data directory: videoExport = new VideoExport(this, "data/video" + i + ".mp4"); And how can i load up the videos that i just created in a case before? Do i need to use an array for that? I'm not sure I understand this question, but you can use any variable you want. Just keep track of where the files are going, and then load them from there.
How use C++ signal to QML with multithreading
I have a program with a general manager which launch a qml interface. This is my constructor: this->m_viewer = ShapedWindows::getInstance(); this->m_comManager = new CComManager(0x80); this->m_convert = new CDataConverter(); this->m_configGenerator = new ConfigurationGenerator(); this->m_workedThread = new QThread(); The creation of my UI m_viewer->setColor("background:transparent"); //remove background m_viewer->engine()->rootContext()->setContextProperty("tr", &m_tr); m_viewer->engine()->rootContext()->setContextProperty("configGene", m_configGenerator); m_viewer->engine()->rootContext()->setContextProperty("generalManager", this); m_viewer->setMainQmlFile(QStringLiteral("qml/MyApp/HomePage.qml")); m_viewer->setFlags (Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); m_viewer->setIcon(QIcon("qml/MyApp/images/Logo.bmp")); m_viewer->setTitle("MyApp"); m_viewer->showExpanded(); m_tr.setLanguage("en"); m_configGenerator->initialise(); this->m_comManager->moveToThread(this->m_workedThread); this->m_convert->moveToThread(this->m_workedThread); this->m_configGenerator->moveToThread(this->m_workedThread); this->moveToThread(this->m_workedThread); this->m_workedThread->start(); When we click on a button I send this: emit this->currentActionChanged("Connexion en cours ..."); if(this->m_comManager->StartCom(937500, 3, 0x81, 3, 0xC1)){ emit this->connexionStateChanged(true); emit this->currentActionChanged("Connexion réussie"); vector<char> memoryAdd; memoryAdd.push_back(0x00); memoryAdd.push_back(0x00); memoryAdd.push_back(0xA0); QByteArray dataRead; emit this->currentActionChanged("Lecture de la carte en cours ..."); this->m_comManager->RMBA(7, 0x23, 3, 0x63, memoryAdd, 12, dataRead); emit this->currentActionChanged("Lecture de la carte terminée"); if(0 < dataRead.size()){ vector<string> config = this->m_convert->ConvertToString(dataRead); this->m_configGenerator->setConfig(config); } Sleep(1000); emit this->connexionStateChanged(!this->m_comManager->StopCom(3, 0x82, 3, 0xC2)); emit this->currentActionChanged("Déconnexion réussie"); } Then I set my generalManager in a new thread. Other objects are set to this new thread but not my IHM class. The problem is when I emit a signal from a class which are in my second thread, as a generalManager signal, my application crash. Qt note this issue ASSERT: "engine->jsStackTop >= mark" in file ....\include\QtQml\5.2.0\QtQml/private/../../../../../src/qml/jsruntime/qv4scopedvalue_p.h, line 74
Using strings with if statements
I have this code: public UILabel Error; void OnRegister(GameObject g) { if (Error.text.Equals("That e-mail address is in use. Use password recovery if you forgot your password.")) { Error.text= "Inserisci un indirizzo di posta elettronica (email) valido. Questa operazione e’ importante per recuperare la tua parola chiave (password), nel momento in cui l’hai dimenticata."; return; } } What i wanted to do is when the string is entered to the UILabel, when a button(having the function OnRegister) it would translate the string to italian. Thank you for the help :)