将JFrame与连续输入流一起使用

我正在尝试实现从我的redboard的串口读取的代码,并根据它读取的内容重新绘制一个圆圈。 这样做的最终目的是使用Robot类来实现实际的光标控制,但我首先想要了解更多有关Java的信息,因此我首先尝试使用一些基本图形来实现它。

总结一下我的问题,我不知道如何使用静态方法不断变化的输入来使用JFrame。

访问JAR的串口可以在http://fazecast.github.io/jSerialComm/找到

Arduino以“UpLeft”,“Up”,“UpRight”,“Left”,“Center”,“Right”,“DownLeft”,“Down”,“Down”,“Up”等forms连续写入基于FPGA加速度计系统的序列。彻头彻尾”。 然后Java程序应该抓住它并相应地重新绘制一个圆圈。

我能够打开COMM3并打印从我的硬件收到的正确方向,但每当我尝试应用JFrame时,我都会迷路。 我发现了很多ActionListener教程,但是这个实现应该是连续的,不依赖于鼠标或键盘事件。 因此,我不知道如何使用paintComponent()和painter()方法,因为main方法是静态的。

非常感谢您的宝贵时间!

import java.awt.Color; import java.awt.Graphics; import java.util.Scanner; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JSlider; import com.fazecast.jSerialComm.*; public class Main extends JPanel{ public void paintComponent(Graphics g, int x, int y) { super.paintComponent(g); g.setColor(Color.MAGENTA); g.fillOval(x, y, 20, 20); } public void painter(int x, int y, int velx, int vely){ x = x + velx; y = y + vely; repaint(); } public static void main(String[] args) { int x = 0, y = 0, velx = 0, vely = 0; SerialPort ports[] = SerialPort.getCommPorts(); System.out.println("Select a Port:"); SerialPort port = ports[1]; Graphics g; if(port.openPort()){ System.out.println("Successfully opened the port."); } else { System.out.println("Unable to open the port."); } port.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0); JFrame jf = new JFrame(); Main main = new Main(); jf.setTitle("Window"); jf.setSize(600, 400); jf.setVisible(true); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.add(main); Scanner data = new Scanner(port.getInputStream()); while(data.hasNextLine()) { System.out.println(data.nextLine()); try{String dir = data.nextLine(); if(dir.equals("UpLeft")) { velx = -1; vely = -1; } if(dir.equals("Up")) { velx = 0; vely = -1; } if(dir.equals("UpRight")) { velx = 1; vely = -1; } if(dir.equals("Left")) { velx = -1; vely = 0; } if(dir.equals("Center")) { velx = 0; vely = 0; } if(dir.equals("Right")) { velx = 1; vely = 0; } if(dir.equals("DownLeft")) { velx = -1; vely = 1; } if(dir.equals("Down")) { velx = 0; vely = 1; } if(dir.equals("DownRight")) { velx = 1; vely = 1; } System.out.println(velx); System.out.println(vely); } catch(Exception e) {}; } } } 

建议:

  1. 从静态main方法中读取InputStream并将其读入其自己的类中。
  2. 这个类应该扩展SwingWorker 。 您必须阅读Swutch中的Concurrency教程,以全面了解如何使用此类。 它将帮助您在后台线程中执行长时间运行的流读取,然后将获取的数据安全地传递到Swing事件线程上的Swing GUI中。
  3. 流中的所有读取都应该在此类的doInBackground()方法中完成。 从Scanner / Stream获取String,并调用worker的publish(...)方法将String传递给此方法。
  4. 给你的Swing GUI一个公共方法,比如public void getPortText(String text)
  5. 在Worker中使用protected void process(List chunks)方法覆盖。 使用for循环遍历块List ,通过调用GUI的getPortText(...)方法将数据传递到Swing GUI。
  6. 在GUI的getPortText方法中,更改GUI类字段的状态,velX和velY字段可以工作,然后调用repaint()
  7. 在GUI(JPanel)的paintComponent方法覆盖中,使用velX和velY字段来更改绘制的内容。
  8. 当然,工作人员需要对可视化GUI的引用才能使其正常工作(所有这些都需要“正确连接”)。
  9. 您的main方法中包含Graphics变量。 摆脱它,因为它在那个位置是危险的。 避免在paintComponent中调用paintComponent方法或方法之外使用Graphics对象。 避免给你的类图形字段。 对此的主要例外是如果您使用从BufferedImage中提取的Graphics对象。

成功