来自另一个类的 SerialPortEventListener
基本上我的程序应该显示一个框架,其中面板根据来自我的电脑串行连接的“输入”数据(整数值)在屏幕上绘制一个点。
问题是:如何将值从串口“传输”到OTHER类Frame并调用REPAINT()方法?????????
鉴于通过控制台我通过 UART 正确接收了每个数据,我使用的方法是通过 EventDriven...我得到的数据没问题...它们在控制台中输出,我得到的正是我预期的值。但是由于创建主框架和子面板的类是另一个类,因此每次收到数据时如何从事件驱动例程调用重绘方法???
这是 MainProgram 的代码(它显示框架并在西侧创建一个子面板):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JRootPane;
public class ArtificialHorizon{
/**
* Artificial Horizont program
* written in Java 1.6.12 (on Debian 5.0 Lenny)
*
* @author wilhem
* starting date: 15 Januar 2010
*
* last update: 18 Januar 2010
*/
/********************************
* Getting the size of the screen
********************************/
private Dimension dimScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
private int xLocation;
private int yLocation;
/**************************
* Definition of the frame
* for the main application
*************************/
@SuppressWarnings("static-access")
public void start(){
JFrame mainFrame = new JFrame("Artificial Horizont");
mainFrame.setUndecorated(true);
mainFrame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(1024, 768);
xLocation = (dimScreenSize.width- mainFrame.getWidth()) / 2;
yLocation = (dimScreenSize.height - mainFrame.getHeight()) / 2;
mainFrame.setLocation(xLocation, yLocation);
mainFrame.setResizable(true);
mainFrame.setLayout(new BorderLayout());
/********************************************
* Creating the Left PANEL
* which contains the Left Artificial Horizon
* for FILTERED Outputs (Processed by Kalman)
********************************************/
ArtificialHorizonPanel leftPanel = new ArtificialHorizonPanel();
ArtificialHorizonPanel rightPanel = new ArtificialHorizonPanel();
mainFrame.getContentPane().add(BorderLayout.WEST, leftPanel);
mainFrame.setVisible(true);
/************************************************
* Create the class RS232 and the Object "serial"
***********************************************/
SerialConnection serial = new SerialConnection("/dev/ttyUSB0", 9600);
}
public static void main(String[] args) {
ArtificialHorizon artificialHorizon = new ArtificialHorizon();
artificialHorizon.start(); // Starting the application
}
}
Hre 是子面板的类(请注意,代码尚未完成......因为我无法“读取”和重新绘制当收到新数据时面板上的 drwa):
import gnu.io.SerialPortEventListener;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
public class ArtificialHorizonPanel extends JPanel{
/************************************
* In this Class the Artificial Horizon
************************************/
/****************************
* Defining instance variables
****************************/
private Color blueSky;
private Color orangeEarth;
private Dimension dimPanel;
private Point2D centerPoint;
private int side = 4;
/************************************
* Thic constructor will create
* the initial panel for the Horizon
************************************/
public ArtificialHorizonPanel(){
dimPanel = new Dimension(400, 700);
setPreferredSize(dimPanel);
setBackground(Color.black);
centerPoint = new Point2D.Double(dimPanel.getWidth()/2, dimPanel.getHeight()/2); // Create a point in the middle of the panel
blueSky = new Color(10, 112, 156);
orangeEarth = new Color(222, 132, 14);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle2D rect = new Rectangle2D.Double((centerPoint.getX() - side/2), (centerPoint.getY() - side/2), side, side);
g2d.setPaint(Color.orange);
g2d.draw(rect);
}
}
这是串行数据类的代码...(工作完美):
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class SerialConnection implements SerialPortEventListener{
private Enumeration portList = null;
private CommPortIdentifier portId = null;
private String defaultPort = null;
private boolean portFound = false;
private int baudRate = 0;
private SerialPort serialPort = null;
private DataInputStream is = null;
private BufferedReader inStream;
/********************************
* Constructor for the base class
*******************************/
public SerialConnection(String defaultPort, int baudrate){
this.defaultPort = defaultPort;
checkPorts(); // Call a method for checking ports on the System
}
/************************************
* This method checks the presence of
* ports on the System, in affirmative
* case initializes and configures it
* to receive data on the serial port
***********************************/
public void checkPorts(){
/***************************************
* Get a list of all ports on the system
**************************************/
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("List of all serial ports on this system:");
while(portList.hasMoreElements()){
portId = (CommPortIdentifier)portList.nextElement();
if(portId.getName().equals(defaultPort)){
portFound = true;
System.out.println("Port found on: " + defaultPort);
initialize(); // If Port found then initialize the port
}
}
if(!portFound){
System.out.println("No serial port found!!!");
}
}
public void initialize(){
/**********************
* Open the serial port
*********************/
try{
serialPort = (SerialPort)portId.open("Artificial Horizont", 2000);
} catch (PortInUseException ex){
System.err.println("Port already in use!");
}
// Get input stream
try{
is = new DataInputStream(serialPort.getInputStream());
} catch (IOException e){
System.err.println("Cannot open Input Stream " + e);
is = null;
}
try{
serialPort.setSerialPortParams(this.baudRate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException ex){
System.err.println("Wrong settings for the serial port: " + ex.getMessage());
}
try{
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
} catch (UnsupportedCommOperationException ex){
System.err.println("Check the flow control setting: " + ex.getMessage());
}
// Add an event Listener
try{
serialPort.addEventListener(this);
} catch (TooManyListenersException ev){
System.err.println("Too many Listeners! " + ev);
}
// Advise if data available to be read on the port
serialPort.notifyOnDataAvailable(true);
}
/**********************************
* Method from interface definition
*********************************/
public void serialEvent(SerialPortEvent event){
inStream = new BufferedReader(new InputStreamReader(is), 5);
String rawInput = null;
switch(event.getEventType()){
case SerialPortEvent.BI:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.FE:
case SerialPortEvent.OE:
case SerialPortEvent.PE:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
try {
while((rawInput = inStream.readLine()) != null){
System.out.println(rawInput);
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!HERE I GET THE VALUE FROM THE SERIAL PORT AND THOSE MUST BE "VISIBLE" TO THE SUBPANEL CLASS IN ORDER AND RUN THE METHOD REPAINT!!!!!!!!!!!!!!!!!!!!!
*/
}
inStream.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
break;
default:
break;
}
}
}
再次...整个代码运行,但我让框架和子面板工作并进入背景是通过串行连接获得的值,但在控制台中......
basically my program should display a frame in which a panel draw a point on the screen according to "input" data (integer values) coming from a serial connection on my pc.
The problem is: how to "transfer" values from the serial port to the OTHER class Frame and call the REPAINT() method??????????
Given that via console I receive every data correctly via UART, the method I used is via EventDriven...Data I get are ok...they are outputted in the console and I get exactly the value I expected. But since the class that creates the main frame and a subpanel is another class, how to call repaint method from the eventdriven routine every time I receive a data????
Here is the code for the MainProgram (it displays the frame and create a subpanel on the west side):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JRootPane;
public class ArtificialHorizon{
/**
* Artificial Horizont program
* written in Java 1.6.12 (on Debian 5.0 Lenny)
*
* @author wilhem
* starting date: 15 Januar 2010
*
* last update: 18 Januar 2010
*/
/********************************
* Getting the size of the screen
********************************/
private Dimension dimScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
private int xLocation;
private int yLocation;
/**************************
* Definition of the frame
* for the main application
*************************/
@SuppressWarnings("static-access")
public void start(){
JFrame mainFrame = new JFrame("Artificial Horizont");
mainFrame.setUndecorated(true);
mainFrame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(1024, 768);
xLocation = (dimScreenSize.width- mainFrame.getWidth()) / 2;
yLocation = (dimScreenSize.height - mainFrame.getHeight()) / 2;
mainFrame.setLocation(xLocation, yLocation);
mainFrame.setResizable(true);
mainFrame.setLayout(new BorderLayout());
/********************************************
* Creating the Left PANEL
* which contains the Left Artificial Horizon
* for FILTERED Outputs (Processed by Kalman)
********************************************/
ArtificialHorizonPanel leftPanel = new ArtificialHorizonPanel();
ArtificialHorizonPanel rightPanel = new ArtificialHorizonPanel();
mainFrame.getContentPane().add(BorderLayout.WEST, leftPanel);
mainFrame.setVisible(true);
/************************************************
* Create the class RS232 and the Object "serial"
***********************************************/
SerialConnection serial = new SerialConnection("/dev/ttyUSB0", 9600);
}
public static void main(String[] args) {
ArtificialHorizon artificialHorizon = new ArtificialHorizon();
artificialHorizon.start(); // Starting the application
}
}
Hre is the class for the Subpanel (please note that the code is not finished yet...because I cannot "read" and repaint the drwa on the panel when a new data has been received):
import gnu.io.SerialPortEventListener;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JPanel;
public class ArtificialHorizonPanel extends JPanel{
/************************************
* In this Class the Artificial Horizon
************************************/
/****************************
* Defining instance variables
****************************/
private Color blueSky;
private Color orangeEarth;
private Dimension dimPanel;
private Point2D centerPoint;
private int side = 4;
/************************************
* Thic constructor will create
* the initial panel for the Horizon
************************************/
public ArtificialHorizonPanel(){
dimPanel = new Dimension(400, 700);
setPreferredSize(dimPanel);
setBackground(Color.black);
centerPoint = new Point2D.Double(dimPanel.getWidth()/2, dimPanel.getHeight()/2); // Create a point in the middle of the panel
blueSky = new Color(10, 112, 156);
orangeEarth = new Color(222, 132, 14);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle2D rect = new Rectangle2D.Double((centerPoint.getX() - side/2), (centerPoint.getY() - side/2), side, side);
g2d.setPaint(Color.orange);
g2d.draw(rect);
}
}
and here is the code for the serialdata class...(works pefectly):
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.TooManyListenersException;
public class SerialConnection implements SerialPortEventListener{
private Enumeration portList = null;
private CommPortIdentifier portId = null;
private String defaultPort = null;
private boolean portFound = false;
private int baudRate = 0;
private SerialPort serialPort = null;
private DataInputStream is = null;
private BufferedReader inStream;
/********************************
* Constructor for the base class
*******************************/
public SerialConnection(String defaultPort, int baudrate){
this.defaultPort = defaultPort;
checkPorts(); // Call a method for checking ports on the System
}
/************************************
* This method checks the presence of
* ports on the System, in affirmative
* case initializes and configures it
* to receive data on the serial port
***********************************/
public void checkPorts(){
/***************************************
* Get a list of all ports on the system
**************************************/
portList = CommPortIdentifier.getPortIdentifiers();
System.out.println("List of all serial ports on this system:");
while(portList.hasMoreElements()){
portId = (CommPortIdentifier)portList.nextElement();
if(portId.getName().equals(defaultPort)){
portFound = true;
System.out.println("Port found on: " + defaultPort);
initialize(); // If Port found then initialize the port
}
}
if(!portFound){
System.out.println("No serial port found!!!");
}
}
public void initialize(){
/**********************
* Open the serial port
*********************/
try{
serialPort = (SerialPort)portId.open("Artificial Horizont", 2000);
} catch (PortInUseException ex){
System.err.println("Port already in use!");
}
// Get input stream
try{
is = new DataInputStream(serialPort.getInputStream());
} catch (IOException e){
System.err.println("Cannot open Input Stream " + e);
is = null;
}
try{
serialPort.setSerialPortParams(this.baudRate,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException ex){
System.err.println("Wrong settings for the serial port: " + ex.getMessage());
}
try{
serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
} catch (UnsupportedCommOperationException ex){
System.err.println("Check the flow control setting: " + ex.getMessage());
}
// Add an event Listener
try{
serialPort.addEventListener(this);
} catch (TooManyListenersException ev){
System.err.println("Too many Listeners! " + ev);
}
// Advise if data available to be read on the port
serialPort.notifyOnDataAvailable(true);
}
/**********************************
* Method from interface definition
*********************************/
public void serialEvent(SerialPortEvent event){
inStream = new BufferedReader(new InputStreamReader(is), 5);
String rawInput = null;
switch(event.getEventType()){
case SerialPortEvent.BI:
case SerialPortEvent.CD:
case SerialPortEvent.CTS:
case SerialPortEvent.DSR:
case SerialPortEvent.FE:
case SerialPortEvent.OE:
case SerialPortEvent.PE:
case SerialPortEvent.RI:
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
break;
case SerialPortEvent.DATA_AVAILABLE:
try {
while((rawInput = inStream.readLine()) != null){
System.out.println(rawInput);
/*
!!!!!!!!!!!!!!!!!!!!!!!!!!!!HERE I GET THE VALUE FROM THE SERIAL PORT AND THOSE MUST BE "VISIBLE" TO THE SUBPANEL CLASS IN ORDER AND RUN THE METHOD REPAINT!!!!!!!!!!!!!!!!!!!!!
*/
}
inStream.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
break;
default:
break;
}
}
}
Again...the whole code runs but I get the frame and the subpanel working and in backgrounf the values got by serial connection but inthe console...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
SwingWorker 非常适合此目的。 此处讨论了相关示例并概述了此处。顺便说一句,请务必在 EDT。
SwingWorker is ideal for this. There are related examples discussed here and outlined here. As an aside, be sure to build your GUI on the EDT.