トップページ > dsPIC入門 > Javaでハイパーターミナル(13)
以下、最終版の4つのクラスです。今回は4つのファイルに分けて保存することを仮定しました。 1つのJavaファイルとして保存する場合は、ファイル名を“serial_canvas.java”として、 インポート文は重複する部分を削除します。 また、これまで何度も実験のためにserial_canvas*.javaやMainFrame.javaというクラスを作って来ました。 これらのファイルがあると過去のバージョンのクラスを読み込んでしまう可能性があります。 そこで、念のためにこの最終版はこれまでとは別のフォルダに保存することをおすすめします。 一括してコンパイルするには“javac *.java”コマンドです。
ダブルクリックで起動するファイルを作成 したい場合はjarファイルを作るを参照してください。
ファイル名は“serial_canvas.java”として保存します。
//******************************************************************************
//Javaでハイパーターミナル
//******************************************************************************
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import gnu.io.*;
//******************************************************************************
//メイン・クラス
public class serial_canvas
{
public static void main(String args[])
{
//============================================================================
//Windows仕様のルック・アンド・フィールに変更。
try
{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
}
catch(Exception e)
{
}
MainFrame frame = new MainFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.setVisible(true);
}
}
ファイル名は“MainFrame.java”として保存します。
//******************************************************************************
//メインウィンドウを管理するクラス
//******************************************************************************
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import gnu.io.*;
class MainFrame extends JFrame
{
Serial_Class serial;
MainFrame()
{
super("serial-canvas");
serial = new Serial_Class();
//============================================================================
//コンテントペインを作成。
JPanel cp = new JPanel();
cp.setLayout(null);
setContentPane(cp);
//============================================================================
//使用COMポートのためのコンボボックス
JLabel com_label = new JLabel("COMポート :");
cp.add(com_label);
com_label.setBounds(50,20,100,20);
cp.add(serial.com_combo);
serial.com_combo.setBounds(120,20,80,20);
//============================================================================
//ボーレートのためのコンボボックス
JLabel baud_label = new JLabel("ボー・レート :");
cp.add(baud_label);
baud_label.setBounds(250,20,100,20);
cp.add(serial.baud_combo);
serial.baud_combo.setBounds(350,20,80,20);
//============================================================================
//テキストフィールドを作成。
Font font = new Font("SansSerif",Font.PLAIN,16);
serial.tx.setFont(font);
serial.tx.setLineWrap(true);
serial.tx.addKeyListener(new KeyInput());
serial.scrollPane.setBounds(50,50,400,300);
cp.add(serial.scrollPane);
//============================================================================
//ボタンを作成。
JButton bt1 = new JButton(new open_action());
cp.add(bt1);
bt1.setBounds(50,400,150,40);
JButton bt2 = new JButton(new close_action());
cp.add(bt2);
bt2.setBounds(300,400,150,40);
//ここまでがコンストラクタです。
}
//******************************************************************************
class open_action extends AbstractAction
{
//COMポートを開く際の処理
open_action()
{
putValue(Action.NAME,"接続");
}
public void actionPerformed(ActionEvent e)
{
serial.open();
}
}
//******************************************************************************
class close_action extends AbstractAction
{
//COMポートを閉じる際の処理
close_action()
{
putValue(Action.NAME,"切断");
}
public void actionPerformed(ActionEvent e)
{
serial.close();
}
}
//******************************************************************************
class KeyInput extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
String txt_temp;
String[] txt_temp_array;
int lineNum;
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{
serial.tx.append("\n");
txt_temp = serial.tx.getText();
txt_temp_array = txt_temp.split("\n",0);
lineNum = txt_temp_array.length - 1;
serial.Serial_puts(txt_temp_array[lineNum]+"\r");
}
}
}
}
ファイル名は“Serial_Class.java”として保存します。
//******************************************************************************
//シリアル通信担当のクラス。Serial_Baseクラスを継承。
//******************************************************************************
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import gnu.io.*;
class Serial_Class extends Serial_Base
{
//=============================================================================
//クラスのフィールド
JComboBox com_combo;
JComboBox baud_combo;
JTextArea tx;
JScrollPane scrollPane;
//=============================================================================
//コンストラクタ
Serial_Class()
{
//テキストエリアを作成
tx = new JTextArea();
//スクロールペインを作成して、その上にテキストエリアを貼り付けておきます。
scrollPane = new JScrollPane(tx);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//COMポート用のコンボボックスを作成して、アイテムを入れておきます。
com_combo = new JComboBox();
com_combo.addItem("COM1");
com_combo.addItem("COM2");
com_combo.addItem("COM3");
com_combo.addItem("COM4");
com_combo.addItem("COM5");
com_combo.addItem("COM6");
com_combo.addItem("COM7");
com_combo.addItem("COM8");
com_combo.addItem("COM9");
com_combo.addItem("COM10");
//デフォルト設定
com_combo.setSelectedItem("COM5");
//ボー・レート用のコンボボックスを作成して、アイテムを入れておきます。
baud_combo = new JComboBox();
baud_combo.addItem("4800");
baud_combo.addItem("9600");
baud_combo.addItem("19200");
baud_combo.addItem("38400");
baud_combo.addItem("57600");
baud_combo.addItem("115200");
baud_combo.addItem("230400");
//デフォルト設定
baud_combo.setSelectedItem("115200");
}
//=============================================================================
//ポートオープンの関数
void open()
{
//正常にオープンできたかを調べるのに使うflagです。
boolean flag;
//コンボボックスから、選択されているCOMポート名を取得します。文字列にしておきます。
String COM_Name = (com_combo.getSelectedItem()).toString();
//コンボボックスから、選択されているボー・レートを取得します。int型に直しておきます。
int Baud_Rate = Integer.parseInt((baud_combo.getSelectedItem()).toString());
//開く。
flag = Serial_open(COM_Name,Baud_Rate);
//正常にオープンできたなら…
if(flag)
{
try
{
//受信イベントを登録します。
port.addEventListener(new SerialPortListener());
//このメソッドを呼んでおかないと、イベントが監視されません…。
port.notifyOnDataAvailable(true);
}
catch(Exception e){}
tx.append("接続しました。\n\n");
}
}
//=============================================================================
//ポートクローズの関数
void close()
{
//正常にクローズできたかを調べるのに使うflagです。
boolean flag;
//閉じる。
flag = Serial_close();
//正常にクローズできたなら…
if(flag)
{
tx.append("切断しました。\n\n");
}
}
//*****************************************************************************
//内部クラスとして、イベントリスナを記述します。
class SerialPortListener implements SerialPortEventListener
{
//============================================================================
//受信イベント発生時に呼び出されるメソッド
public void serialEvent(SerialPortEvent Serial_event)
{
//受信データ1文字分を置いておくための変数です。
int received_data = 0;
//バッファーです。ここに受信データをためていきます。
StringBuffer buffer = new StringBuffer();
//受信完了の合図があれば・・・
if(Serial_event.getEventType() == SerialPortEvent.DATA_AVAILABLE)
{
//--------------------------------------------------------------------------
//breakが来るまで回し続ける部分。
while(true)
{
try
{
received_data = in.read();// 入力ストリームから読み込み
//文字無しの場合はすぐに抜けます。
if(received_data == -1)
{
break;
}
//文字列の終わりではない場合は、バッファーに付け加えていきます。
if((char)received_data != '\r')
{
buffer.append((char)received_data);
}
//文字列の終わりなら、最後に改行コードを足して、テキストエリアへ表示。
else
{
//テキストエリア改行。
buffer.append('\n');
//バッファの内容を文字列にして、テキストエリアへ追加。
tx.append(buffer.toString());
//バッファを一応、空にしておきます。
buffer.delete(0,buffer.length()-1);
//これをやらないと、受信イベントごとに自動でテキストエリアがスクロールしてくれません。
tx.setCaretPosition(tx.getText().length());
break;
}
}
catch(IOException ex){}
}
//while()文ここまで。
//--------------------------------------------------------------------------
}
}
}
//内部クラスここまで。
//*****************************************************************************
}
ファイル名は“Serial_Base.java”として保存します。
//****************************************************************************************
//汎用シリアル通信用クラス
//****************************************************************************************
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import gnu.io.*;
class Serial_Base
{
//=============================================================================
//クラスのフィールド
SerialPort port;
CommPortIdentifier comID;
InputStream in;
OutputStream out;
String comName;
int baudRate;
//=============================================================================
//ポートオープンの関数
boolean Serial_open(String COM_NAME,int BAUD_RATE)
{
comName = COM_NAME;
baudRate = BAUD_RATE;
//----------------------------------------------------------------------------
//ポートIDを取得
try
{
//フィールドのcomNameの名前で新規にCOMポートを取得
comID = CommPortIdentifier.getPortIdentifier(comName);
}
catch(Exception e1)
{
JOptionPane.showMessageDialog(null,"ポートを取得できませんでした。","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
//----------------------------------------------------------------------------
//もしポートが既に開いていないなら、ポートを開いて各種設定を行います。
if(comID.isCurrentlyOwned()==false)
{
try
{
//シリアルポートのインスタンスを生成
port = (SerialPort)comID.open("serial_canvas",2000);
//ボーレート、データビット数、ストップビット数、パリティを設定
port.setSerialPortParams(baudRate,SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE );
//フロー制御はしない
port.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
//入出力ストリームの設定
in = port.getInputStream();
out = port.getOutputStream();
}
catch(Exception e2)
{
JOptionPane.showMessageDialog(null,"うまく開けませんでした。","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
}
else
{
JOptionPane.showMessageDialog(null,"すでに開いています。","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
//=============================================================================
//ポートクローズの関数
boolean Serial_close()
{
if(comID.isCurrentlyOwned())
{
try
{
//全部クローズ。
port.close();
in.close();
out.close();
}
catch(IOException e3)
{
JOptionPane.showMessageDialog(null,"うまく閉じれませんでした。","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
}
else
{
JOptionPane.showMessageDialog(null,"すでに閉じています。","Serial_Base.open()",JOptionPane.INFORMATION_MESSAGE);
return false;
}
return true;
}
//=============================================================================
//文字列送信関数
void Serial_puts(String str)
{
try
{
//String型の引数をbyte配列にする。
byte[] data = str.getBytes();
//アウトプットストリームを介して送信します。
out.write(data);
out.flush();
}
catch(Exception e4)
{
}
}
}