2

我正在用 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");
}
}

第二个代码块是启动应用程序的主类。有什么建议么?

4

2 回答 2

2

你在线程的轨道上。

您可能对Java 跟踪中的并发教程感兴趣。我会想一些类似于 and 的notify东西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();
}
于 2013-04-04T22:53:44.637 回答
2

我强烈建议使用类似SwingWorker.

您不想做的是在 Event Dispatching Thread 上执行任何会阻塞 UI 的操作,这将阻止您更新 UI(包括显示消息)并且 UI 无法自行更新,使其看起来像是挂起的。

查看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- 这是一个概念证明,您需要填写功能

于 2013-04-04T23:34:54.977 回答