나는 항복한다. 차단중인 항목을 찾으려면 몇 주가 지난 후 일련 번호 데이터가 내 코드의 그래픽 부분에서 업데이트되지 않도록하십시오. 처음 자바 프로그래밍. 약 15 년의 프로그래밍 경험을 가진 마이크로 및 내 자신의 문제를 해결하는 데 익숙해졌지만 여기에는 전술이 생산적 인 지점을 넘어갑니다. 내 응용 프로그램은 두 개의 파일로 구성됩니다.그래픽 업데이트
하나의 파일은 RXTX 프로젝트에서 유래하여 여러 패킷으로 전송 된 일련의 데이터를 매초 두 번씩 두 번씩 수신합니다. 이것은 매력 (시간이 걸렸습니다)처럼 작동하고 캡처 된 데이터가 정확하고 안정적임을 나타냅니다. 안정적입니다.
다른 파일은 그래픽이며 최종 사용자가 을 읽고 때때로 값을 쓸 수있는 약 80 개의 메뉴로 구성됩니다. 탐색은 지금까지 버튼과 스크롤 막대의 마우스 이벤트로 수행됩니다. 이 부분도 제대로 작동합니다. 값을 읽고, 변경하고 저장할 수 있습니다.
내가 붙어있는 부분은 업데이트 된 값이 직렬 파일에서 업데이트되지 않으므로 그래픽 화면입니다. 행운을 빌어 수백 가지 예제와 튜토리얼 (이 사이트에서 많은 )을 따라 가려고 시도했습니다.
객체 관련 언어의 개념은 나에게 새롭고 여전히 혼란 스럽습니다. 내 문제가 상속과 수업에 관련되는지 확실히 확인하십시오. 스레드는 다른 후보입니다 ... 을 실행하고 내 문제를 제시하고 다른 사람이 무엇이 잘못 볼 수 있기를 기대하는 가장 작은 크기로 코드를 줄이십시오.
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();
}
}
}
그리고 그래픽
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;
}
}
}
절대로 절대 양보하지 말고 – mKorbel
나는 스윙에 익숙하지 않지만 메서드 호출 간의 관계를 설명 할 수 있습니까? 내가 얻지 못하는 것을 설명하는 것은 약간 까다 롭다. 첫째로'SerialComm'은'dspUpdate()'를 호출한다. 이 메소드는'repaint'를 호출 할 것이고 (좋은 것 같아요), 다시 칠하는 것은'dspUpdate'를 호출하는'paintComponent'를 다시 호출할까요? – phineas
@phineas 스윙의 Concurency 문제가 있습니다. GUI에 대한 모든 업데이트는 EDT – mKorbel