我正在用 Java 开发一个应用程序,它将从 Xbee 设备接收到的数据上传到在线数据库。功能在那里,一切正常,但是在开发 GUI(使用 WindowsPro Builder)时,一切都变糟了。问题是,应用程序需要能够检测到 Xbee 设备,如果未连接,请等待它连接 - 无限期(或直到关闭)。我已经有一种方法可以检测串口是否是 Xbee 设备;就像我说的,一切正常,除非我将它与 GUI 集成。
我遇到的问题是创建一个 GUI,它首先检测 Xbee 设备是否已连接,如果没有,则显示一条消息,通知用户连接设备以继续。同时(在显示消息时),我需要调用扫描串行端口的方法。我正在考虑线程,但我已经有一段时间没有使用它们了。请注意,该方法在应用程序启动时已经运行过一次,以便尝试连接。我没有要显示的代码,因为我所做的只是放置基本框架、按钮等(还没有事件)。我是 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");
}
}
第二个代码块是启动应用程序的主类。有什么建议么?