Processingでシリアルポート選択のUIを作る(JComboBox版)
ProcessingでArduinoとかとシリアル通信するとき、ポートと通信速度をリストから選べるUIが欲しいですよね。はい、作りましょう。
import processing.awt.*; import java.awt.*; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import processing.serial.*; class SerialSetting { final int COMBO_PORT_WIDTH = 100; final int COMBO_PORT_HEIGHT = 20; final int COMBO_RATE_WIDTH = 80; final int COMBO_RATE_HEIGHT = 20; final Integer[] list_rate = {300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200, 230400, 250000, 500000, 1000000, 2000000}; String[] list_port = null; JComboBox combo_port; JComboBox combo_rate; String current_port = null; int current_rate = 0; Serial serial = null; PApplet parent = null; SerialSetting(PApplet app, int x, int y, String default_port, int default_rate) { parent = app; String[] list_port = Serial.list(); Canvas canvas =(Canvas)surface.getNative(); JLayeredPane pane =(JLayeredPane)canvas.getParent().getParent(); // combobox(port) combo_port = new JComboBox(list_port); combo_port.addActionListener( new SelectActionListener() ); combo_port.setBounds( x, y, COMBO_PORT_WIDTH, COMBO_PORT_HEIGHT); pane.add(combo_port); // combobox(rate) combo_rate = new JComboBox(list_rate); combo_rate.addActionListener( new SelectActionListener() ); combo_rate.setBounds(x + COMBO_PORT_WIDTH + 10, y, COMBO_RATE_WIDTH, COMBO_RATE_HEIGHT); pane.add(combo_rate); // select items combo_port.setSelectedItem(default_port); combo_rate.setSelectedItem(default_rate); combo_port.updateUI(); combo_rate.updateUI(); } class SelectActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // update params current_port = (String)combo_port.getItemAt(combo_port.getSelectedIndex()); current_rate = (int)combo_rate.getItemAt(combo_rate.getSelectedIndex()); // connect if ( serial != null ) { serial.stop(); } if ( current_port != null ) { serial = new Serial(parent, current_port, current_rate ); } } } } // ----------------------------------------------------------------------------------- // ここから下がメインプログラム。ここより上を別ファイルにすると良い。 SerialSetting setting; void setup() { size(400, 300); // 表示位置 x=30, y=20, デフォルトのポート=COM16, デフォルトの速度=115200 // ここで指定したポートおよび速度が実際のリストにない場合は、リスト先頭のものが選ばれる。 setting = new SerialSetting(this, 30, 20, "COM16", 115200); } void draw() { } void serialEvent(Serial port) { if ( port.available() > 0 ) { String s = port.readStringUntil('\n'); if ( s != null ) { print(s); } } }
以前も作った
以前にもこういうの作ってるんですが、前回はリストの表示にControlP5を使ってて、今回はSwingのJComboBoxを使ってます。
kougaku-navi.hatenablog.com
メモ
- Processing v3対応。PAppletまわりの仕様が2→3で変わってるので2.xでは使えないかも。
- プログラム実行中にUSBケーブルを抜き差ししたときにリフレッシュできるようにしたかったんですが、ケーブルを抜いてからポートのリストが更新されるまで数秒ラグがあるみたいで、そのせいで存在しないポートに接続しようとして怒られる、みたいなことになって結局あきらめました。基本、プログラム実行中にケーブルを抜くのはやめましょう。
- シリアルポートを同時に2個以上使いたいときにSerialSettingオブジェクトを2個作ると、コンフリクトが発生するかも。