gpt4 book ai didi

java - 从 SwingWorker 接收数据

转载 作者:行者123 更新时间:2023-11-30 02:11:56 26 4
gpt4 key购买 nike

我正在尝试使用 SwingWorker 通过串行端口读取数据。但是,执行此代码后我没有收到任何输出。通过添加行

JOptionPane.showConfirmDialog(null, "Cancel", "Cancel this task?", JOptionPane.DEFAULT_OPTION);

按照 SwingWorker not executing doInBackGround() 中的建议我只收到输出“Reading”/n“Done”,并且我的 getPortText 方法未被调用。用于显示可用端口的 IF block 也不会执行。

fazecast SerialComm JAR 可以在 http://fazecast.github.io/jSerialComm/ 找到

非常感谢所有帮助,我已经在这个问题上坚持了好几天了!

import java.util.List;
import java.util.Scanner;

import javax.swing.JOptionPane;
import javax.swing.SwingWorker;

import com.fazecast.jSerialComm.SerialPort;

public class PortWorkerCheck {

public static void main(String[] args) {
Worker worker = new Worker();
worker.execute();
}

public static void getPortText(String dir) {
System.out.println(dir);
}

static class Worker extends SwingWorker<Void, String>{
boolean portcheck = false;
SerialPort comPort[] = SerialPort.getCommPorts();
SerialPort port;
protected void done() {
System.out.println("Done");
}

@Override
protected Void doInBackground() throws Exception {
String data;
//This if block attempts to list available ports and have the user select one.
if (portcheck = false) {
int i = 1;
System.out.println("Select a port:");
for(SerialPort ports : comPort) {
System.out.println(i++ + ". " + ports.getSystemPortName());
}

Scanner s = new Scanner(System.in);
int chosenPort = s.nextInt();
port = comPort[chosenPort - 1];
portcheck = true;
if(port.openPort()) {
System.out.println("Port opened successfully");
}
port.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
}

publish("Reading");
Scanner read = new Scanner(port.getInputStream());
data = read.nextLine();
publish(data);
return null;
}

//My process should call getPortText, which should then display the received data.
@Override
protected void process(List<String> chunks) {
for(String line : chunks) {
portcheck = true;
PortWorkerCheck.getPortText(line);
}
}
}

}

最佳答案

问题:

  • 您发布的代码不会创建 Swing GUI,因此 Swing 事件线程永远不会启动。这意味着当您的 main 方法退出并且任何其他非守护线程退出时,您的程序也会退出。该发布/处理方法可能会在执行任何有用操作之前就终止。解决方案:不要在没有 Swing GUI 的情况下使用 SwingWorkers。创建两者并连接它们。
  • 您的代码仅尝试从端口读取一行数据,然后退出。您需要一个连接到读取端口的扫描器的 while 循环
  • 您的 if block boolean 测试是错误的(根据评论)。切勿以这种方式进行 if 测试:if (portcheck = false) {。相反,安全地执行此操作:if (!portcheck) {
  • if block 中的所有代码都不应该出现。您不应该将 Swing 事件驱动程序与基于控制台的扫描程序混合在一起。数据应通过 Swing GUI 获取。
  • 您声明:“我将worker.execute()放入while(true)循环中”——不,不要这样做。您不会重复执行该工作程序,而是仅执行一次。这是一种使用一次就扔掉的对象类型。相反,while 循环进入扫描器获取数据的工作线程内部

类似于:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.InputStream;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

// not a class that I'm familiar with
import com.fazecast.jSerialComm.SerialPort;

public class PortWorkerCheckPanel extends JPanel {

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
PortWorkerCheckPanel portCheckPanel = new PortWorkerCheckPanel();
JFrame frame = new JFrame("Port Check");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(portCheckPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}

private JTextArea textArea = new JTextArea(20, 50);
private StartWorkerAction startAction = new StartWorkerAction(this);

public PortWorkerCheckPanel() {
textArea.setFocusable(false);
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(startAction));

setLayout(new BorderLayout());
add(scrollPane);
add(btnPanel, BorderLayout.PAGE_END);
}

public void appendPortText(String text) {
textArea.append(text + "\n");
}

private static class StartWorkerAction extends AbstractAction {
private PortWorkerCheckPanel portCheckPanel;

public StartWorkerAction(PortWorkerCheckPanel portCheckPanel) {
super("Start Worker");
this.portCheckPanel = portCheckPanel;
}

@Override
public void actionPerformed(ActionEvent arg0) {
Worker worker = new Worker(portCheckPanel);
worker.addPropertyChangeListener(new WorkerListener());
worker.execute();
}
}

static class WorkerListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
Worker worker = (Worker) evt.getSource();
try {
worker.get();
} catch (InterruptedException | ExecutionException e) {
// TODO handle any exceptions here
e.printStackTrace();
}
}
}
}

static class Worker extends SwingWorker<Void, String> {
boolean portcheck = false;

// Note that I have no idea if this part, the SerialPort code, is
// correct
// as I do not use this utility
SerialPort comPort[] = SerialPort.getCommPorts();
SerialPort port;
private PortWorkerCheckPanel portCheckPanel;

public Worker(PortWorkerCheckPanel portCheckPanel) {
this.portCheckPanel = portCheckPanel;
}

protected void done() {
System.out.println("Done");
}

@Override
protected Void doInBackground() throws Exception {
String data;

// this code in the if block should all be done interactively in the
// GUI,
// not using a console-based Scanner the information should then be
// passed
// into this worker via a constructor parameter
if (!portcheck) {
int i = 1;
System.out.println("Select a port:");
for (SerialPort ports : comPort) {
System.out.println(i++ + ". " + ports.getSystemPortName());
}

Scanner s = new Scanner(System.in);
int chosenPort = s.nextInt();
port = comPort[chosenPort - 1];
portcheck = true;
if (port.openPort()) {
System.out.println("Port opened successfully");
}
port.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
}

publish("Reading");
Scanner read = new Scanner(port.getInputStream());

while (read.hasNextLine()) {
data = read.nextLine();
publish(data);
}
if (read != null) {
read.close();
}
return null;
}

// My process should call getPortText, which should then display the
// received data.
@Override
protected void process(List<String> chunks) {
for (String line : chunks) {
portcheck = true;
// PortWorkerCheckPanel.getPortText(line);
portCheckPanel.appendPortText(line);
}
}
}
}

关于java - 从 SwingWorker 接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49807948/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com