Tôi đầu hàng. Hãy thử một vài tuần ngay bây giờ để tìm hiểu xem dữ liệu nối tiếp nào đã được nhận một phần dữ liệu nối tiếp của mã của tôi bị chặn. Lập trình lần đầu trong Java. Có khoảng 15 năm kinh nghiệm lập trình micros và tôi được sử dụng để giải quyết các vấn đề của riêng tôi nhưng điều này vượt quá điểm mà ở đó rằng chiến thuật là hiệu quả. Ứng dụng của tôi bao gồm hai tệp.Đang cập nhật đồ họa
Một tệp xuất phát từ dự án RXTX và bắt dữ liệu nối tiếp được gửi trong một số gói hai lần một giây. Điều này hoạt động giống như một sự quyến rũ (mất một thời gian) và tôi có thể thấy rằng dữ liệu bị bắt là chính xác và ổn định.
Tệp khác là đồ họa và bao gồm khoảng 80 menu nơi người dùng cuối có thể đọc và đôi khi viết giá trị. Việc điều hướng được thực hiện bằng các sự kiện chuột trên các nút và thanh cuộn cho đến nay. Phần này cũng hoạt động như mong muốn. Giá trị có thể được đọc, thay đổi và lưu vv ..
Phần mà tôi bị kẹt là giá trị cập nhật từ tệp nối tiếp không bao giờ cập nhật màn hình đồ họa. Đã cố gắng làm theo hàng trăm ví dụ và hướng dẫn (nhiều từ trang web này) mà không có may mắn.
Khái niệm về ngôn ngữ liên quan đến đối tượng là mới đối với tôi và vẫn khá khó hiểu. Khá chắc chắn vấn đề của tôi liên quan đến thừa kế và các lớp học. Chủ đề là một ứng cử viên khác ... Đã cắt giảm mã xuống kích thước nhỏ nhất vẫn chạy và trình bày vấn đề của tôi và hy vọng ai đó có thể thấy những gì sai.
package components;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.SwingUtilities;
public class SerialComm extends ScreenBuilder implements java.util.EventListener {
InputStream in;
public SerialComm() {
super();
}
public interface SerialPortEventListener
extends java.util.EventListener {
}
void connect(String portName) throws Exception {
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier("COM1");
if (portIdentifier.isCurrentlyOwned()) {
System.out.println("Error: Port is currently in use");
} else {
CommPortIdentifier.getPortIdentifier("COM1");
System.out.println("" + portName);
CommPort commPort = portIdentifier.open("COM1", 2000);
if (commPort instanceof SerialPort) {
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_2, SerialPort.PARITY_NONE);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
serialPort.addEventListener(new SerialComm.SerialReader(in));
serialPort.notifyOnDataAvailable(true);
(new Thread(new SerialComm.SerialReader(in))).start();
// TX functionality commented for now
// (new Thread(new SerialWriter(out))).start();
} else {
System.out.println("Error: Only serial ports are handled by this example.");
}
}
}
public class SerialReader extends SerialComm implements Runnable,
gnu.io.SerialPortEventListener {
public SerialReader(InputStream in) {
this.in = in;
}
@Override
public void run() {
count=11; // just for test. run is normally empty
count2=count; // and real code runs within serialEvent()
System.out.println("SerialReader " + count);
dspUpdate(); // do some desperate stuff in graphics file
System.out.println("Post Update " + count);
}
@Override
public void serialEvent(SerialPortEvent event) {
System.out.println("SerialEvent");
switch (event.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE:
try {
synchronized (in) {
while (in.available() < 0) {
in.wait(1, 800000);
} //in real code RX data is captured here twice a sec
} //and stored into buffers defined in ScreenBuilder
//dspUpdate() is called from here to make ScreenBuilder update its screen
//That never happens despite all my attempts
} catch (IOException e) {
System.out.println("IO Exception");
} catch (InterruptedException e) {
System.out.println("InterruptedException caught");
}
}
}
}
/* "main" connect PC serial port and start graphic part of application
* To demonstrate problem with no serial data stream present
* order of init between serial port and graphics are switched
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ScreenBuilder screen = new ScreenBuilder();
screen.createAndShowGUI();
System.out.println("Created GUI");
}
});
try {
(new SerialComm()).connect("COM1");
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
}
Và đồ họa nộp
package components;
import java.awt.*;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.*;
public class ScreenBuilder extends JPanel implements ActionListener {
public Font smallFont = new Font("Dialog", Font.PLAIN, 12);
Color screenColor;
Color lineColor;
short btn=0;
short count;
short count2;
Button helpButton;
public static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "
+ SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("JUST A TEST");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ScreenBuilder());
f.pack();
f.setVisible(true);
}
public void dspButton() {
setLayout(null);//
helpButton = new Button("?");
helpButton.setLocation(217, 8); // set X, Y
helpButton.setSize(16, 14); //Set Size X, Y //
helpButton.addActionListener(this);
add(helpButton);
setBackground(Color.black);
helpButton.setBackground(Color.black);
screenColor = Color.black;
helpButton.setForeground(Color.white);
lineColor = Color.white;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == helpButton) {
count2++;
System.out.println("Pressed Button ");
repaint();
}
}
public ScreenBuilder() {
setBorder(BorderFactory.createLineBorder(Color.black));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(240, 180);
}
public void dspUpdate() {
/*
* This function is called from SerialComm
* Should be called when serial packets have arrived (twice a second)
* and update screen with values from serial stream
* For now just a test var to validate that values from SerialComm
* get to here (they do)
*/
count++;
System.out.println("Update Count " + count);
System.out.println("Update Count2 " + count2);
// revalidate(); // another futile attempt to update screen
// repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(lineColor);
g.setFont(smallFont);
count++;
g.drawString("" + count, 130, 20);
g.drawString("" + count2, 150, 20);
if (btn == 0) {
dspButton();
btn = 1;
}
}
}
không bao giờ bàn giao, không bao giờ đầu hàng – mKorbel
Tôi không quen với việc xoay vòng, nhưng bạn có thể giải thích mối quan hệ giữa các cuộc gọi phương thức không? Đó là một chút khó khăn để giải thích những gì tôi không nhận được: Ở nơi đầu tiên 'SerialComm' gọi' dspUpdate() '. Phương thức này sẽ gọi 'repaint' (tốt tôi nghĩ), gọi lại' paintComponent' gọi 'dspUpdate' là gì? – phineas
@phineas s/ông có vấn đề với Concurency trong Swing, có tất cả các bản cập nhật cho GUI phải được thực hiện trên EDT, – mKorbel