GUI冻结了。当我按下CLOSE按钮时,我想连续发送到串口“1”

时间:2015-12-11 14:22:07

标签: java user-interface serial-port processing

我正在使用处理和控制IP5库,我的代码有问题。当我按下关闭按钮时,我想连续3秒延迟发送到串口“1”,当我按下打开按钮时我想要发送到串口“2”再过3秒,但在关闭按钮后,GUI冻结,我无法再按任何按钮。

import controlP5.*;
import processing.serial.*;
ControlP5 cp5;
Textlabel myTextlabelA;
String serial_list;                // list of serial ports
int serial_list_index = 0;         // currently selected serial port 
int num_serial_ports = 0;  
Serial serial_port = null;        // the serial port
Button b1,b2;

void setup() {

size(800,600);
noStroke();
 cp5 = new ControlP5(this); 

// get the list of serial ports on the computer
serial_list = Serial.list()[serial_list_index];

// get the number of serial ports in the list
 num_serial_ports = Serial.list().length;

myTextlabelA = cp5.addTextlabel("label")
                .setText("Close-Open")
                .setPosition(430,15)
                .setColorValue(0xffffff00)
                .setFont(createFont("Georgia",20))
                ;

Button b1=cp5.addButton("Close")
 .setValue(128)
 .setPosition(400,50)
 .setSize(40, 20)
 .updateSize()
 ;

 Button b2=cp5.addButton("Open")
 .setValue(128)
 .setPosition(500,50)
 .setSize(40, 20)
 .updateSize()
 ;

  Button bUP=cp5.addButton("^") //Up arrow
 .setValue(128)
 .setPosition(140,10)
 .setSize(40, 20)
 .updateSize()
 ;

 Button bDOWN=cp5.addButton("v") //Down arrow
 .setValue(128)
 .setPosition(140,50)
 .setSize(40, 20)
 .updateSize()
 ;

  Button bCONNECT=cp5.addButton("Connect") //Connect button
 .setValue(128)
 .setPosition(190,10)
 .setSize(100, 25)
 .updateSize()
 ;

 Button bDISCONNECT=cp5.addButton("Disconnect") //Disconnect button
 .setValue(128)
 .setPosition(190,45)
 .setSize(100, 25)
 .updateSize()
 ;

 Button bREFRESH=cp5.addButton("Refresh") //Resresh button
 .setValue(128)
 .setPosition(190,80)
 .setSize(100, 25)
 .updateSize()
 ;    

b1.setColorBackground( color( 255,0,0 ) );    //initial b1 color
b2.setColorBackground( color( 128,0,0 ) );   //initial b2 color
bREFRESH.setColorBackground( color (128,128,0) ); //initial Refresh color
b1.setSwitch(true); //convert button to switch 
b1.setOff(); //set True or False
}
 void draw() {
   background(0);
DrawTextBox("Select Port", serial_list, 10, 10, 120, 60);
}
public void controlEvent(ControlEvent theEvent) {
println("Button Pressed:"+theEvent.getController().getName());

if(theEvent.controller().getName()=="^") 
if (serial_list_index > 0) {
  // move one position up in the list of serial ports
  serial_list_index--;
  serial_list = Serial.list()[serial_list_index];
}

if(theEvent.controller().getName()=="v") 
if (serial_list_index > 0) {
  // move one position up in the list of serial ports
  serial_list_index--;
  serial_list = Serial.list()[serial_list_index];
}

 if(theEvent.controller().getName()=="Connect") 
  if (serial_port == null) {
  // connect to the selected serial port
  serial_port = new Serial(this, Serial.list()[serial_list_index], 9600);
  println("Connection Succesfull");
}

if(theEvent.controller().getName()=="Disconnect") 
 if (serial_port != null) {
  // disconnect from the serial port
  serial_port.clear();
  serial_port.stop();
  serial_port = null;
  println("Disonnection Succesfull");
}

if(theEvent.controller().getName()=="Refresh") {
serial_list = Serial.list()[serial_list_index];
num_serial_ports = Serial.list().length;
println("Refresh Succesfull");
}     

if(theEvent.controller().getName()=="Close") 
     if (serial_port != null) {
       while (theEvent.controller().getName()=="Close"){
  // Send 1 to serial port
  serial_port.write(49);
   println("sent 1");
   delay(3000);}
}

if(theEvent.controller().getName()=="Open") 
if (serial_port != null) {
  // Send 2 to serial port
  serial_port.write(50);
   println("sent 2");
}
}
 void DrawTextBox(String title, String str, int x, int y, int w, int h)
{
fill(255);
rect(x, y, w, h);
fill(0);
textAlign(LEFT);
textSize(14);
text(title, x + 10, y + 10, w - 20, 20);
textSize(12);  
text(str, x + 10, y + 40, w - 20, h - 10);
}
编辑:所以@KevinWorkman先生我来到这些:我从public void controlEvent(ControlEvent theEvent)获取了部分代码并将其放在draw()中,所以我有这个:

 void draw() {
 background(0);
 if (mousePressed) {
  timeClicked = millis();
 }
 if (millis() < timeClicked + 1000) {
   // Send 1 to serial port
        serial_port.write(49);
        println("sent 1");
 }

 DrawTextBox("Select Port", serial_list, 10, 10, 120, 60);

 }

但是当我尝试连接GUI时没有响应。我认为在mousePressed()我会说出我想要的事件,但是怎么做呢?

2 个答案:

答案 0 :(得分:0)

您正在冒险进入线程的世界。这是一个非常重要的主题,但我会尝试为您简化它:

主题视为工作人员,一次只能一件事

Processing使用单个线程绘制内容并处理用户交互。这通常是一件好事,因为这意味着您可以根据用户交互来绘制内容。

但是,你正在调用<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit&hl=en"></script> ,告诉该线程要等待。 在等待时无法执行任何其他操作。这就是为什么您无法点击任何按钮,屏幕上没有任何内容,而是在等待。

您最好的选择是重构您的代码,使其不再依赖delay()函数。尝试使用delay()函数来代替您的时间,这样您就不会在UI线程上等待。

你也可以尝试创建另一个线程来进行等待,而UI线程可以做到这一点,但除非你知道你在做什么,否则我不会推荐它。

修改:以下是每次点击时使用millis()功能显示椭圆1秒的示例:

millis()

您必须修改代码才能使用类似的逻辑来执行延迟。如果你遇到困难,尝试一下并提出另一个问题 - 不要忘记加入MCVE

答案 1 :(得分:0)

您从UI Thread发送命令。在其他线程中调用您的发送函数。