I'm developing an application, in Java, that uploads data received from an Xbee device to an online database. The functionality is there and everything works, but when developing a GUI (with WindowsPro Builder), everything goes sour. The thing is, the app needs to be able to detect the Xbee device and if not connected, wait for it to be connected - indefinitely (or until closed). I already have a method that detects if the serial port is an Xbee device; like I said, everything works, except when I integrate it with the GUI.
The problem I'm having is creating a GUI that first detects if an Xbee device is connected, and if not, display a message notifying the user to connect the device in order to continue. At the same time (while displaying the message), I need to be calling the method that scans serial ports. I'm thinking threads, but I haven't used those in a while. Please note that the method already ran once, when the application started, in order to try and connect. I've no code to show, since all I did was put up the basic frames, buttons, etc (no events yet). I'm new to GUI programming in Java, any suggestions?
Update: So I kinda tried to implement what MadProgrammer suggested, which I'm kinda convinced it works given the SwingWorker tutorial, but nothing happens.The only thing that runs is setting up the GUI. Up next is the code:
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");
}
}
The second block of code is the main class which launches the application. Any suggestions?