Olá pessoal.
Este é meu primeiro tópico aqui, fiquei muito interessado pois vi que o povo daqui manda bem.
É o seguinte:
Quero criar uma GUI com alguns campos de texto e botões que leia desses campos e passe as strings para um array de ints com o valor ascii para que, ao rodar o robot, ele escreva num determinado local da tela esssas strings alternadamente num loop infinito.
Tive diversos problemas visto que é meu primeiro programa :) mas contornei todos eles inclusive com ajuda daqui. Foram eles: como passar a string pra array de int-ascii, como fazer os botoes funcionarem (actionListener) como fazer o robot escrever e talz.
O robot funciona liso se for pra escrever uma vez só as strings. Quando coloco para loop ele trava a gui (os botões e labels que deveriam mostrar o status não mudam mais quando vai pro sleep) mas escreve com tempo e ordem correta.
O fato é que eu queria manter a gui funcionando pois se eu quero interromper o loop infinito tenho que derrubar o programa no eclipse :( pois os botões estão congelados.
Já fiz minha pesquisa na net e descobri que isso pode ser contornado com Thread, poréééém não tem nenhum lugar assim genial que ajude um java-virgem com linguagem passo-a-passo e exemplo.
De qualquer modo, vou colocar o código aqui.
(Grrrr :? , acabei de ver, não tenho mais a versão que trava a gui mas roda o loop corretamente)
Vou postar a versão com minha tentativa de Thread.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class TesteGUI {
JButton sleepButton;
JTextField field1;
JTextField field2;
public Boolean sleep=true;
public Boolean robotRunning=false;
public Robot rob;
String tempEmote1="";
String tempEmote2="";
int [] emote_1;
int [] emote_2;
public int firstRun=0;
//Getters - Setters Block
public Boolean getSleep() {
return sleep;
}
public void setSleep(Boolean sleep) {
this.sleep = sleep;
}
public Boolean getRobotRunning() {
return robotRunning;
}
public void setRobotRunning(Boolean robotRunning) {
this.robotRunning = robotRunning;
}
public String getTempEmote1() {
return tempEmote1;
}
public void setTempEmote1(String tempEmote1) {
this.tempEmote1 = tempEmote1;
}
public String getTempEmote2() {
return tempEmote2;
}
public void setTempEmote2(String tempEmote2) {
this.tempEmote2 = tempEmote2;
}
// End of Getters - Setters block
/**
* @param args
* @throws AWTException
*/
public static void main(String[] args) throws AWTException{
TesteGUI gui= new TesteGUI();
gui.go(gui,gui.rob); //creates the GUI and starts the robot
}
public void go(final TesteGUI gui, final Robot rob){
final robotLoop loop=new robotLoop();
final Thread thread=new Thread(loop);
JFrame frame= new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel leftPanel= new JPanel();
JPanel rightPanel= new JPanel();
//Left Panel Component's declarations
leftPanel.setLayout(new GridLayout(4, 1));
JLabel lab1 = new JLabel();
lab1.setText("Dofus BREEDER");
JLabel statusLabel = new JLabel("Status: ", JLabel.RIGHT);
field1=new JTextField();
field1.setText("enter emote1");
field1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
gui.setTempEmote1(field1.getText()); //text field content loaded into a temporary string
}});
field2=new JTextField();
field2.setText("");
field1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
gui.setTempEmote2(field2.getText()); //text field content loaded into a temporary string
}});
//Fill the left panel with its components
leftPanel.add(lab1);
leftPanel.add(field1);
leftPanel.add(field2);
leftPanel.add(statusLabel);
//left panel is complete
//Right Panel Component's declarations
rightPanel.setLayout(new GridLayout(4, 1));
final JLabel lab2 = new JLabel();
lab2.setText(" ");
final JLabel status = new JLabel();
status.setFont(new Font("Comic Sans", Font.PLAIN, 18));
status.setOpaque(true);
status.setBackground(Color.RED); //status label: shows if the program is sleeping or running
status.setText(" sleeping "); //first run, he is sleeping by definition
sleepButton= new JButton("Run");
sleepButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
gui.setTempEmote1(field1.getText()); //assure that those temporary strings will receive the text field data
gui.setTempEmote2(field2.getText()); //even if the user do not type 'enter' at the end the text field
gui.emote_1=gui.converte(tempEmote1);
gui.emote_2=gui.converte(tempEmote2);//convert the string to array of int - without the '/' in first position
if (gui.getSleep()==true){
sleepButton.setText("Sleep");
gui.setSleep(false);
status.setText(" running ");
status.setBackground(Color.GREEN); //status label shows running
if (firstRun==0){
thread.start(); //Starts the ROBOT
firstRun++;}
else{thread.resume();}
}
else {
sleepButton.setText("Run");
gui.setSleep(true);
status.setText(" sleeping ");
status.setBackground(Color.RED); //status label shows sleeping
thread.suspend();
}
}
}); //will change the program's state running<->sleeping
JButton exitButton= new JButton("exit");
exitButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}); //just click the button to exit - (or you can click the top-right 'x' )
//Fill the right panel with its components
rightPanel.add(exitButton);
rightPanel.add(lab2);
rightPanel.add(sleepButton);
rightPanel.add(status);
//right panel is complete
//Fill the frame with the two panels and make it visible
frame.add(BorderLayout.WEST, leftPanel);
frame.add(BorderLayout.EAST, rightPanel);
frame.setBounds(400, 400, 200, 150);
frame.setVisible(true);
//GUI complete!
}
public int[] converte(String emoteToConvert){ //takes a String and returns an int array with char-by-char ASCII code
int[] emoteToReturn=new int[emoteToConvert.length()];
String upperEmoteToConvert=emoteToConvert.toUpperCase();
for(int i=0; i < emoteToConvert.length()-1;i++){
emoteToReturn[i]=(int) upperEmoteToConvert.charAt(i+1); //int i = (int) s -> i receives the ascii code of string s
}
return emoteToReturn;
}
class robotLoop implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
//robot with infinite loop
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//takes 5s to start
//Starts the infinite loop
while(sleep==false){
for (int i = 0; i < emote_1.length; i++) {
if (i==0){
rob.keyPress(KeyEvent.VK_DIVIDE);//first emote character must be '/'
}
else{
rob.keyPress(emote_1[i-1]);
}
rob.delay(1000);
}
try {
Thread.sleep(4000); // 8-9 seconds total time
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rob.keyPress(KeyEvent.VK_ENTER);
//First emote done
//8-9 seconds to write and enter the oher, 4-5 to write + 4 to enter
for (int i = 0; i < emote_2.length; i++) {
if (i==0){
rob.keyPress(KeyEvent.VK_DIVIDE);//first emote character must be '/'
}
else{
rob.keyPress(emote_2[i-1]);
}
rob.delay(1000);
}
try {
Thread.sleep(4000); // 8-9 seconds total time
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
rob.keyPress(KeyEvent.VK_ENTER);
}
}
}
}
Rodando hoje, como está, me responde:
[color=red]Exception in thread "Thread-0" java.lang.NullPointerException
at RobotDemo.TesteGUI$robotLoop.run(TesteGUI.java:434)
at java.lang.Thread.run(Unknown Source)[/color]
434 é a linha: rob.keyPress(KeyEvent.VK_DIVIDE);//first emote character must be '/'
Já adianto que eu fui modificando diversos lugares do programa pra tentar resolver e com isso, provavelmente, ficaram alguns lixos pra traz. Desculpem-me por isso, tentarei não fazer mais porque também me atrapalha bastante...
(pelo menos os comentários, imagino eu, estão bem feitos)
Agradeço ae pela ajuda.
Abraços
ps1: aconselho vocês, caso rodem o meu programa, deixar o 'focus' em algum campo de texto, como num notepad ou coisa do tipo, pq pra ver se funciona é legal você deixar o robot escrever em algum lugar.
ps2:Acho válido dizer que não estou tendo problemas com string, arrays e etc. meu problema é como fazer o thread parar o programa quando o sleep=true (ou quando o botão de sleep for acionado, o que dá no mesmo).
No momento, não sei porque, o robot não está nem mesmo escrevendo. Está dando nullpointerexception...