下面是我用来打开com端口的代码--它等待用户从控制台扫描器输入数字来打开端口,这个端口列在一个JComboBox中。我有一个带有按钮的事件监听器,我想用它来代替打开com端口。但我不确定是否有一个最好的做法来 "停止 "进一步的执行,直到用户按下按钮来打开端口。控制台扫描器目前很方便地允许程序等待选择)。我只是想让程序只在按下按钮后打开端口时才继续执行。一个jcombo框显示了端口,我可以使用getSelectedIndex()获得端口号。
package testPackage;
import java.awt.BorderLayout;
import java.awt.ItemSelectable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.PrintWriter;
import java.util.Scanner;
import com.fazecast.jSerialComm.*;
import javax.swing.*;
//To test - Select option 5, from select a port dialogue (Com0Com port 6)
//open terminal program - select port Com0Com 7
//send numbers as Ascii
public class Main {
static SerialPort serialPort;
public static void main(String[] args) {
Window1 window1 = new Window1();
JComboBox<String> commList = new JComboBox<>();
window1.add(commList);
JButton bigButton = new JButton("Select Comm port");
window1.add(bigButton);
window1.pack();
window1.setVisible(true);
JLabel label = new JLabel("My label");
window1.add(label, BorderLayout.CENTER);
SerialPort[] ports = SerialPort.getCommPorts();
System.out.println("Select a port:");
int i = 1;
for(SerialPort port : ports) {
System.out.println(i++ + ": " + port.getSystemPortName());
commList.addItem(port.getSystemPortName());
}
bigButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clicked");
label.setText("Selected");
System.out.println("Selected: " + commList.getSelectedItem());
System.out.println("Position: " + commList.getSelectedIndex());
// SerialPort serialPort = ports[commList.getSelectedIndex()];
open_serial();
}
private void open_serial() {
serialPort = ports[commList.getSelectedIndex()];
}
});
Scanner s = new Scanner(System.in);
int chosenPort = s.nextInt();
SerialPort serialPort = ports[chosenPort - 1];
// System.out.println("Chosen port : " + chosenPort);
// System.out.println("Selected: " + commList.getSelectedItem());
// System.out.println("Position: " + commList.getSelectedIndex());
if(serialPort.openPort())
System.out.println("Port opened successfully.");
else {
System.out.println("Unable to open the port.");
s.close();
return;
}
serialPort.setBaudRate(9600);
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
Scanner data = new Scanner(serialPort.getInputStream());
int value = 0;
//Thread thread = new Thread();
PrintWriter output = new PrintWriter(serialPort.getOutputStream());
output.print("Hiya");
output.flush();
System.out.println("printing1");
while(data.hasNextLine()){
System.out.println(value);
try{value = Integer.parseInt(data.nextLine());}catch(Exception e){}
output.print("Received");
output.flush();
}
System.out.println("Done.");
data.close();
s.close();
}
};
//-here is the window1 class
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
public class Window1 extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
JButton BigButton;
public Window1() {
super("Programmer");
setLookAndFeel();
this.setPreferredSize(new Dimension(400, 300));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flo = new FlowLayout();
setLayout(flo);
setVisible(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc) {
// ignore error
}
}
}
但我不确定是否有一个最好的做法来 "停止 "进一步的执行,直到用户按下打开端口的按钮。
我可以想到两种主要的方法来 "暂停 "一个Swing GUI,同时等待用户输入。
SerialPort selectedPort = null;
和其他监听器中的其他地方, 那些不涉及端口选择的监听器, 都在顶部。if (selectedPort == null) { return; }
如果您想了解更多的细节,那么可以考虑创建并发布一个有效的 最小的、可复制的例子 带着您的问题,我可以根据您的需求进行调整。请查看这个宝贵工具的链接。
这里是我的意思的一个例子。运行它来试试。
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.*;
@SuppressWarnings("serial")
public class MyPortExample extends JPanel {
private JTextArea fromPortArea = new JTextArea(20, 40);
private Action sendAction = new SendAction("Send");
private Action setUpPortAction = new SetUpPortAction("Set Up Port", this);
private JTextField toPortField = new JTextField(35);
private JTextField portNameField = new JTextField(15);
private JButton sendTextBtn = new JButton(sendAction);
private PrintStream outFromPort = null;
private MockSerialPort serialPort = null;
public MyPortExample() {
portNameField.setFocusable(false);
JPanel topPanel = new JPanel();
topPanel.add(new JButton(setUpPortAction));
topPanel.add(portNameField);
JScrollPane scrollPane = new JScrollPane(fromPortArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
sendAction.setEnabled(false);
toPortField.setAction(sendAction);
fromPortArea.setFocusable(false);
JPanel sendPanel = new JPanel();
sendPanel.add(toPortField);
sendPanel.add(sendTextBtn);
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane);
add(sendPanel, BorderLayout.PAGE_END);
}
public void setSerialPort(MockSerialPort port) {
this.serialPort = port;
outFromPort = (PrintStream) port.getOutputStream();
InputStream in = port.getInputStream();
new PortWorker(in, fromPortArea).execute();
portNameField.setText(port.getSystemPortName());
sendAction.setEnabled(true);
}
public MockSerialPort getSerialPort() {
return serialPort;
}
private class PortWorker extends SwingWorker<Void, String> {
private Scanner portScanner;
private JTextArea textArea;
public PortWorker(InputStream in, JTextArea fromPortArea) {
this.textArea = fromPortArea;
portScanner = new Scanner(in);
}
@Override
protected Void doInBackground() throws Exception {
while (portScanner.hasNextLine()) {
publish(portScanner.nextLine());
}
return null;
}
@Override
protected void process(List<String> chunks) {
for (String text : chunks) {
textArea.append(text + "\n");
}
}
}
private class SendAction extends AbstractAction {
public SendAction(String name) {
super(name);
putValue(MNEMONIC_KEY, KeyEvent.VK_S);
}
@Override
public void actionPerformed(ActionEvent e) {
if (outFromPort != null) {
String text = toPortField.getText();
outFromPort.println(text);
toPortField.selectAll();
toPortField.requestFocusInWindow();
} else {
System.err.println("No output stream available");
}
}
}
private static class SetUpPortAction extends AbstractAction {
private MyPortExample myPortExample;
public SetUpPortAction(String name, MyPortExample myPortExample) {
super(name);
putValue(MNEMONIC_KEY, KeyEvent.VK_P);
this.myPortExample = myPortExample;
}
@Override
public void actionPerformed(ActionEvent e) {
int messageType = JOptionPane.PLAIN_MESSAGE;
MockSerialPort port = (MockSerialPort) JOptionPane.showInputDialog(myPortExample, "Please select a port",
"Port Selection", messageType, null, MockSerialPort.getCommPorts(), null);
if (port != null) {
myPortExample.setSerialPort(port);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
MyPortExample mainPanel = new MyPortExample();
JFrame frame = new JFrame("MyPortExample");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private static class MockSerialPort {
public static final String TIMEOUT_READ_SEMI_BLOCKING = "timeout read semi blocking";
private String portName;
private int baudRate;
public MockSerialPort(String name) {
this.portName = name;
}
public String getSystemPortName() {
return portName;
}
public OutputStream getOutputStream() {
return System.out;
}
public InputStream getInputStream() {
return System.in;
}
public void setComPortTimeouts(String timeoutReadSemiBlocking, int i, int j) {
// TODO ??? not sure what goes here
}
public void setBaudRate(int baudRate) {
this.baudRate = baudRate;
}
public boolean openPort() {
return true;
}
@Override
public String toString() {
return portName;
}
public static MockSerialPort[] getCommPorts() {
List<MockSerialPort> ports = new ArrayList<>();
for (int i = 0; i < 20; i++) {
ports.add(new MockSerialPort("Port " + (i + 1)));
}
return ports.toArray(new MockSerialPort[] {});
}
}
}
在通过顶部的按钮选择了一个端口之前,GUI是被禁用的,然后底部的JTextField和按钮被启用,以通过以下方式向端口发送数据 .setEnabled(true)
.
这也包含了一个我没有的串口类的 "模拟 "类。