package info.istlab.IoTP; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.util.ArrayList; import java.util.Hashtable; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import com.fazecast.jSerialComm.SerialPort; import com.fazecast.jSerialComm.SerialPortDataListener; import com.fazecast.jSerialComm.SerialPortEvent; public class SerialWindow extends JFrame implements SerialPortDataListener, ActionListener, Runnable, WindowListener { SerialPort sp; JTextField jtf; JTextArea jta; Thread thread; public static Hashtable<String, SerialWindow> hash; static { hash = new Hashtable<String,SerialWindow>(); } public static void check(){ SerialPort[] ports = SerialPort.getCommPorts(); ArrayList<SerialPort> splist_valid = new ArrayList<SerialPort>(); for (SerialPort sp : ports) { String name = sp.getSystemPortName(); if (name.startsWith("cu.usbserial") || name.startsWith("COM")) { splist_valid.add(sp); } } if (splist_valid.size()==1){ SerialPort sp = splist_valid.get(0); App.serialName = sp.getSystemPortName(); } else if (splist_valid.size()==0){ JOptionPane.showMessageDialog(null, "No available serial ports."); } else { SerialSelector.show(splist_valid.toArray(new SerialPort[]{})); } } public static void invoke() { SerialPort[] ports = SerialPort.getCommPorts(); ArrayList<SerialPort> splist_valid = new ArrayList<SerialPort>(); for (SerialPort sp : ports) { String name = sp.getSystemPortName(); if (name.startsWith("cu.usbserial") || name.startsWith("COM")) { splist_valid.add(sp); } } if (splist_valid.size()==1){ SerialPort sp = splist_valid.get(0); SerialWindow sw = new SerialWindow(sp); hash.put(sp.getSystemPortName(), sw); } else if (splist_valid.size()==0){ JOptionPane.showMessageDialog(null, "No available serial ports."); } else { SerialSelector.show(splist_valid.toArray(new SerialPort[]{})); } } public SerialWindow(SerialPort _sp) { super("SerialMonitor " + _sp.getSystemPortName()); sp = _sp; sp.setBaudRate(115200); sp.addDataListener(this); System.out.println(sp.getSystemPortName()); if (!sp.openPort()) { JOptionPane.showMessageDialog(null, "他のプログラムがシリアルポート "+sp.getSystemPortName()+" を使用しています。"); System.out.println("Unable to open the port."); return; } jtf = new JTextField("(ここに入力してEnterを押すと、シリアル送信します)"); jtf.setForeground(Color.GRAY); jtf.addFocusListener(new FocusListener() { @Override public void focusGained(FocusEvent e) { if (jtf.getText().equals("(ここに入力してEnterを押すと、シリアル送信します)")) { jtf.setText(""); jtf.setForeground(Color.BLACK); } } @Override public void focusLost(FocusEvent e) { if (jtf.getText().isEmpty()) { jtf.setForeground(Color.GRAY); jtf.setText("(ここに入力してEnterを押すと、シリアル送信します)"); } } }); getContentPane().add(jtf, BorderLayout.NORTH); jta = new JTextArea(); getContentPane().add(new JScrollPane(jta), BorderLayout.CENTER); // compileB = new JButton("compile"); // compileB.addActionListener(e -> { // compile(e.getActionCommand()); // }); // getContentPane().add(compileB, BorderLayout.SOUTH); setSize(500, 400); setLocation(centerOfScreen(getSize())); setVisible(true); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); jtf.addActionListener(this); addWindowListener(this); // Xをおしたらserial closeする } @Override public int getListeningEvents() { return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; } @Override public void serialEvent(SerialPortEvent event) { try { int evt = event.getEventType(); // System.out.println("Event " + evt + " received"); if (evt == SerialPort.LISTENING_EVENT_DATA_AVAILABLE) { int bytesToRead = sp.bytesAvailable(); if (bytesToRead == -1) { System.out.println("-1 means port is closed."); closeSerialPort(); return; } byte[] newData = new byte[bytesToRead]; sp.readBytes(newData, bytesToRead); String s = new String(newData, "UTF8"); appendToJTA(s); } } catch (Exception ex) { System.err.println(ex.getMessage()); closeSerialPort(); } } void appendToJTA(String s) { if (jta == null) return; if (s.contains("waiting for download")) { closeSerialPort(); //切断のみ。再接続はしない } jta.append(s); int len = jta.getDocument().getLength(); if (jta.getSelectedText() == null) jta.setCaretPosition(len); } void closeSerialPort() { if (sp != null) { if (sp.isOpen()) { System.out.println("close Serial Port"); sp.closePort(); jta.setBackground(Color.lightGray); // thread = new Thread(this); // thread.start(); } // sp = null; } } // ここで、画面中心にウィンドウ表示するため、いろいろ計算する public static Point centerOfScreen(Dimension winSize) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); return new Point((screenSize.width - winSize.width) / 2, (screenSize.height - winSize.height) / 2); } @Override public void actionPerformed(ActionEvent e) { String action = e.getActionCommand(); System.out.println(action); try { String message = action + "\n"; byte[] b = message.getBytes(); System.out.println("send " + b.length + " bytes"); sp.writeBytes(b, b.length); jtf.setText(""); } catch (Exception ex) { System.out.println(ex.getMessage()); } } /** * 再接続用(つかっていない) */ @Override public void run() { appendToJTA("(Waiting to reconnect.)\n"); try { Thread.sleep(10000); } catch (InterruptedException e) { } while (thread != null) { if (!sp.openPort()) { System.out.println("Unable to open the port."); return; } else { thread = null; appendToJTA("Reconnected.\n"); } try { Thread.sleep(2000); } catch (InterruptedException e) { } } } @Override public void windowOpened(WindowEvent e) { } @Override public void windowClosing(WindowEvent e) { closeSerialPort(); } @Override public void windowClosed(WindowEvent e) { closeSerialPort(); } @Override public void windowIconified(WindowEvent e) { } @Override public void windowDeiconified(WindowEvent e) { } @Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } }