我正在开发一个Java应用程序,它将从Xbee设备接收的数据上传到在线数据库。功能就在那里,一切正常,但在开发GUI(使用WindowsPro Builder)时,一切都很糟糕。问题是,应用程序需要能够检测到Xbee设备,如果没有连接,请等待它连接 - 无限期(或直到关闭)。我已经有一种方法可以检测串口是否是Xbee设备;就像我说的,一切正常,除非我将它与GUI集成。
我遇到的问题是创建一个首先检测Xbee设备是否已连接的GUI,如果没有,则显示一条消息,通知用户连接设备以便继续。同时(显示消息时),我需要调用扫描串口的方法。我在考虑线程,但我有一段时间没有使用它们。请注意,该方法已在应用程序启动时运行一次,以便尝试连接。我没有代码可以显示,因为我所做的只是提出了基本的框架,按钮等(还没有事件)。我是Java的GUI编程新手,有什么建议吗?
更新:所以我试图实现MadProgrammer建议的内容,我确信它在SwingWorker教程中有用,但没有任何反应。唯一运行的是设置GUI。接下来是代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.SwingWorker;
public class ConnectionWorker extends SwingWorker<Boolean, String> {
private ConnectionListener callBack;
private Xbee xbee = new Xbee();
private QboComm comm;
public ConnectionWorker(ConnectionListener listener, QboComm comm) {
this.callBack = listener;
this.comm = comm;
}
protected void process(List<String> chunks) {
String msg = chunks.get(chunks.size() - 1);
if (msg.equals("WAITING")) {
comm.publishError();
}
}
protected Boolean doInBackground() throws Exception {
boolean isConnected = false;
this.xbee = QboComm.xbee;
ArrayList<String> list = new ArrayList<String>();
if(!isConnected){
publish("WAITING");
while(!isConnected){
list = xbee.getSerialPorts();
for(String s : list){
isConnected = xbee.connect(s);
if(isConnected){
publish("DONE");
break;
}
}
}
}
return isConnected;
}
protected void done() {
boolean check;
try {
check = get();
if (check) {
comm.removeError();
callBack.connectionEstablished();
} else {
callBack.connectionFailed();
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
import java.awt.EventQueue;
public class QboComm {
private JFrame frmQboCommunicator;
public static Xbee xbee = new Xbee();
private JInternalFrame internalFrame;
private JLabel lblConnected;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
QboComm window = new QboComm();
window.frmQboCommunicator.setVisible(true);
ConnectionListener callback = new ConnectionListener() {
public void connectionEstablished() {
try {
ArrayList<String> list = new ArrayList<String>();
list = xbee.fetch();
DBConnector db = DBConnector.getConnector();
if(db.connect()){
for(String s : list){
db.upload(s.substring(0, 5), s.substring(5));
}
}
db.disconnect();
xbee.printDBList();
} catch (Exception e) {
e.printStackTrace();
}
}
public void connectionFailed() {
//IMPLEMENT
}
};
new ConnectionWorker(callback, window).execute();
}
});
}
/**
* Create the application.
*/
public QboComm() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmQboCommunicator = new JFrame();
frmQboCommunicator.setTitle("Qbo Communicator");
frmQboCommunicator.getContentPane().setBackground(new Color(165, 42, 42));
frmQboCommunicator.getContentPane().setForeground(new Color(211, 211, 211));
frmQboCommunicator.setBounds(100, 100, 450, 300);
frmQboCommunicator.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmQboCommunicator.getContentPane().setLayout(null);
/**
* Connection Error Pop-up
*/
this.internalFrame = new JInternalFrame("Connection Error");
internalFrame.setBorder(new LineBorder(new Color(153, 180, 209), 3));
internalFrame.setBounds(103, 46, 227, 157);
frmQboCommunicator.getContentPane().add(internalFrame);
internalFrame.getContentPane().setLayout(null);
JTextPane txtpnAQboCommunicator = new JTextPane();
txtpnAQboCommunicator.setText("A Qbo Communicator is not connected. Please connect a Qbo Communicator to continue.");
txtpnAQboCommunicator.setEditable(false);
txtpnAQboCommunicator.setBounds(0, 0, 211, 128);
internalFrame.getContentPane().add(txtpnAQboCommunicator);
internalFrame.setVisible(false);
/**
* Application Name
*/
JLabel lblQboCommunicator = DefaultComponentFactory.getInstance().createTitle("QBO COMMUNICATOR");
lblQboCommunicator.setForeground(new Color(255, 255, 255));
lblQboCommunicator.setBackground(new Color(255, 255, 240));
lblQboCommunicator.setHorizontalAlignment(SwingConstants.CENTER);
lblQboCommunicator.setBounds(144, 0, 146, 14);
frmQboCommunicator.getContentPane().add(lblQboCommunicator);
/**
* Connected label, displayed when connected to Xbee device
*/
this.lblConnected = DefaultComponentFactory.getInstance().createLabel("CONNECTED");
lblConnected.setForeground(new Color(255, 255, 255));
lblConnected.setFont(new Font("Tahoma", Font.BOLD, 14));
lblConnected.setHorizontalAlignment(SwingConstants.CENTER);
lblConnected.setBounds(144, 25, 146, 14);
frmQboCommunicator.getContentPane().add(lblConnected);
/**
* Scroll Panel that displays uploaded data
*/
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(53, 65, 344, 131);
frmQboCommunicator.getContentPane().add(scrollPane);
JPanel panel = new JPanel();
panel.setBorder(new LineBorder(new Color(255, 255, 255)));
panel.setBackground(new Color(165, 42, 42));
scrollPane.setViewportView(panel);
/**
* Progress Bar
*/
JProgressBar progressBar = new JProgressBar();
progressBar.setStringPainted(true);
progressBar.setFont(new Font("Tahoma", Font.BOLD, 12));
progressBar.setBackground(new Color(255, 255, 255));
progressBar.setForeground(new Color(255, 140, 0));
progressBar.setBounds(53, 214, 344, 25);
frmQboCommunicator.getContentPane().add(progressBar);
}
public void publishError(){
this.internalFrame.setVisible(true);
this.lblConnected.setText("DISCONNECTED");
}
public void removeError(){
this.internalFrame.setVisible(false);
this.lblConnected.setText("CONNECTED");
}
}
第二个代码块是启动应用程序的主类。有什么建议吗?
答案 0 :(得分:2)
你正在使用线程。
您可能对Java trail中的Concurrency Tutorial感兴趣。我会想到notify
and wait
的内容。例如:
public synchronized guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
上面的代码将等到另一个线程从notify
块或方法调用对象上的synchronized
方法;例如,通过调用此方法:
public synchronized notifyJoy() {
joy = true;
notifyAll();
}
答案 1 :(得分:2)
我强烈建议使用类似SwingWorker
的内容。
你不想做的是在阻止UI的事件调度线程上做任何事情,这将阻止你更新UI(包括显示消息)和UI自我更新,使它看起来像它挂了。
查看Concurrency in Swing了解详情。
Swing是一个事件驱动的环境(我敢肯定),基本上,你希望你的应用程序只是运行直到建立连接,可能会显示某种消息窗口,表明它正在等待连接。
设置一个可以为另一个类提供回调的SwingWorker
,我将是一个相对简单的过程。
import java.awt.EventQueue;
import java.util.List;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class WaitForSwingWorker {
public static void main(String[] args) {
new WaitForSwingWorker();
}
public WaitForSwingWorker() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
ConnectionListener callback = new ConnectionListener() {
@Override
public void connectionEstablished() {
// Continue running the app
}
@Override
public void connectionFailed() {
// Show error message :(
}
};
new ConnectionWorker(callback).execute();
// Execution will continue here...
}
});
}
public interface ConnectionListener {
public void connectionEstablished();
// If possible, you should provide a message as to why...
public void connectionFailed();
}
public class ConnectionWorker extends SwingWorker<Void, String> {
private ConnectionListener callBack;
public ConnectionWorker(ConnectionListener listener) {
callBack = listener;
}
@Override
protected void process(List<String> chunks) {
// Back in the EDT...
String msg = chunks.get(chunks.size() - 1);
if (msg.equals("WAITING")) {
// Show waiting for connection message...
}
}
@Override
protected Void doInBackground() throws Exception {
// Within our own thread
// Establish connection...
if (!isConnected) {
publish("WAITING");
// Wait for incoming connection, this can block...
}
return null;
}
@Override
protected void done() {
// Back in the EDT
if (isConnected) {
// Show failed to connect message?
callBack.connectionEstablished();
} else {
callBack.connectionFailed();
}
}
}
}
nb-这是概念验证,您需要填写功能