📜 ⬆️ ⬇️

JavaFx, a simple COM port terminal

In the life of an embedded developer, there is often a need to interact with a serial port.
And let the RS-232 almost completely supplanted by modern interfaces, the UART does not seem to be going anywhere

Most of the modules (WI-FI, IoT, etc.), demoplat / single-board work or have UART on board.



Terminal programs a huge variety, the most notable - Putty and termianl v1.9b
They do an excellent job, but the difficulties begin when there are more than one open connection.
')
It takes a long time to switch and search for the desired window.

Then an idea arose, why not write a terminal, where each connection will be in a separate tab, and each incoming packet will signal on it. I am sure it is more convenient to 4 terminals scattered across different screens.

The choice was between node webkit, Qt and javaFx. Node webkit was frightened by the possible gluttony, Qt is IMHO long in development / debugging.





The first thing was sketched block diagram



And by the evening there was a relatively working draft.

Probably there is no point in putting all the code here. The project is on the gita .

I present the most interesting part in my opinion:

public class ConnectionData { @FXML //--     public TextArea receiveData; @FXML //--    public TextField sendData; @FXML //-- ( , bind  sendDataProperty,     ) public Button sendButton; // binding private StringProperty sendDataProperty = new SimpleStringProperty(""); //  BlockingQueue<String> rxDataQueue = new LinkedBlockingQueue<>(); @FXML public void initialize() { sendData.textProperty().bindBidirectional(sendDataProperty); sendButton.disableProperty().bind(sendDataProperty.isEmpty()); Task<Void> task = new Task<Void>() { @Override public Void call() throws Exception { //    ,     new MessageConsumer Platform.runLater(() -> new MessageConsumer(rxDataQueue, receiveData, rxDataQueue.size()).start()); return null; } }; new Thread(task).start(); } public class MessageConsumer extends AnimationTimer { private final BlockingQueue<String> messageQueue ; private final TextArea textArea ; private int messagesReceived = 0 ; public MessageConsumer(BlockingQueue<String> messageQueue, TextArea textArea, int numMessages) { this.messageQueue = messageQueue ; this.textArea = textArea ; } @Override public void handle(long now) { List<String> messages = new ArrayList<>(); messagesReceived += messageQueue.drainTo(messages); messages.forEach(msg -> textArea.appendText(msg)); } } public Button getPropertySendButton() { return sendButton; } public String getSendDataProperty() { String sendBuff = sendDataProperty.get(); sendDataProperty.set(""); return sendBuff; } public void clearReceiveData() { //--   flush   receiveData.textProperty().setValue(""); } public void setReceiveData(byte[] buffer) { //       try { rxDataQueue.add(new String(buffer, "UTF-8")); } catch (UnsupportedEncodingException ex) { System.err.print(ex); } } } 

The form class for output is TextField (sendData).

If you directly write data to the buffer and send it directly to TextField, a nullException will occur very soon, since they are in different streams.

For this, as it is not difficult to guess, the queue is used - BlockingQueue rxDataQueue .

Data is received from SerialPort (jssc) and placed in a queue via a call to setReceiveData.

Task task will pick up the accepted item and after sending it will remove it from the queue.

What do you want to get further and what is planned from the functional:

- probably it is necessary to save configs by ports
- ssh client (flexible and intuitive!)
- add custom color to tabs
- bring the interface to a pleasant view, css, JFoenix

Git
Assembled assembly

Source: https://habr.com/ru/post/354954/


All Articles