この記事の例では、Java がマウスを制御して画面ブロードキャストを実装する方法を説明します。皆さんの参考に共有してください。具体的な分析は次のとおりです。
前回の記事「Java での画面共有機能の実装例の分析」では、画面をキャプチャするときにマウスが存在しないと述べましたが、教師インターフェイス上でマウスを表示するには、各スクリーンショットにマウスを描画することができます。ただし、スクリーンショットを 1 つずつ取得するため、表示されるマウスは必然的に少し動かなくなります。以前に Java マウス コントロール アプレットを作成しました。この方法でマウスのデモを見ることができます。
実装方法も非常に簡単です。前の 2 つの記事では、それぞれマウスを使用しないマウス制御機能と画面共有機能を実装しました。以下では、この 2 つを簡単に分析してみましょう。
サーバー側では、SendScreenImg と SendMouseMessage は 2 つのツール クラスとみなされ、それぞれ異なるポートをリッスンし、両方とも Thread クラスを実装し、スレッド プール ExecutorService クラスを使用してそれらを制御します。
マウス情報と画像情報を一緒に送信する方法がまだわからないため、2 つのポートが使用されています。おそらく、画像をバイト配列に変換し、配列の前にマウス座標を置くことができます。マウス座標を送信する速度は画像を送信するよりも速いため、支離滅裂になります。時間があるときにもう一度試してください。
クライアントの例えは上記と同じです。
コードは次のとおりです。
サーバ:
主なプログラム:
次のようにコード code をコピーします:/*
※スクリーンブロードキャストクラスは、スレッドプールを利用して、スクリーンショット情報を送信するクラスとマウス情報を送信するクラスの2つのツールクラスを呼び出します。
*/
パブリック クラス BroderCast {
public static void main(String[] args)
{
新しい BroderCast();
System.out.println("開始");
}
パブリック BroderCast()
{
ExecutorService exector = Executors.newFixedThreadPool(2);
exector.execute(new SendScreenImg());
exector.execute(new SendMouseMessage());
}
}
スクリーンショット コードを送信します:
次のようにコードをコピーします。
java.awt.Rectangle をインポートします。
java.awt.Robotをインポートします。
java.awt.Toolkitをインポートします。
インポート java.awt.image.BufferedImage;
java.io.DataOutputStreamをインポートします。
インポート java.io.IOException;
java.net.ServerSocketをインポートします。
java.net.Socketをインポートします。
java.util.zip.ZipEntryをインポートします。
インポート java.util.zip.ZipOutputStream;
インポートjavax.imageio.ImageIO;
/*
* ツール: 教師側から生徒側にスクリーンショット情報を送信します。マウス情報はなく、ポート 8002 が使用されます。
※送信した画像のコンポーネントにマウス情報を描画し、生徒のインターフェース上でマウス情報を確認できる機能はまだ実装されていません。
*
*/
パブリッククラスSendScreenImgはThreadを拡張します
{
public int サーバーポート=8002;
プライベートサーバーソケットサーバーソケット;
プライベートロボットロボット。
公開寸法画面。
パブリック Rectangle 長方形;
private Socket ソケット。
public static void main(String args[])
{
新しいSendScreenImg().start();
}
public voidchangeServerPort(intserverPort)
{
if(this.serverPort == サーバーポート) return;
試す{
this.serverSocket.close(); //まず現在のポートを閉じる必要があります
this.serverPort = サーバーポート;
サーバーソケット = 新しいサーバーソケット(this.serverPort);
サーバーソケット.setSoTimeout(8000000);
}catch(例外 e){}
}
//ソケット接続ロボットを開いて画面サイズを取得する構築メソッド
パブリック SendScreenImg()
{
試す {
サーバーソケット = 新しいサーバーソケット(getServerPort());
サーバーソケット.setSoTimeout(864000000);
ロボット = 新しいロボット();
} catch (例外 e) {
e.printStackTrace();
}
screen = Toolkit.getDefaultToolkit().getScreenSize(); //メイン画面のサイズを取得します。
rect = new Rectangle(screen) // 対応するサイズの長方形を作成します。
}
@オーバーライド
public void run()
{
// スクリーンショット メッセージの受信をリアルタイムで待機します
while(true){
試す {
ソケット = サーバーソケット.accept();
ZipOutputStream zip = new ZipOutputStream(new DataOutputStream(socket.getOutputStream()));
zip.setLevel(9); //圧縮レベルを設定します。
試す{
BufferedImage img = robot.createScreenCapture(rect);
zip.putNextEntry(new ZipEntry("test.jpg"));
ImageIO.write(img, "jpg", zip);
if(zip!=null)zip.close();
System.out.println("学生ポートが接続されています");
キャッチ (IOException ioe) {
System.out.println("制御対象端末: 切断");
}
キャッチ (IOException ioe) {
System.out.println("接続エラー");
} ついに {
if (ソケット != null) {
試す {
ソケット.クローズ();
} キャッチ (IOException e) {
}
}
}
}
}
}
マウス情報を送信します。
次のようにコード code をコピーします:/*
※ツールクラス:マウス情報を取得し、生徒端末に送信
*/
public class SendMouseMessage extends Thread{
プライベート int OPERATE_PORT = 8001;
プライベートServerSocketサーバー。
private Socket ソケット。
プライベート文字列operateStr;
public static void main(String[] args)
{
新しい SendMouseMessage().start();
}
public SendMouseMessage(){
試す {
サーバー = 新しいサーバーソケット(OPERATE_PORT);
//JOptionPane.showMessageDialog(null, "リスニングを開始しました");
} キャッチ (IOException e1) {
e1.printStackTrace();
}
}
//複数のスレッドがワイヤレス ループでクライアントを監視します
public void run()
{
while(true){
ポイント point = MouseInfo.getPointerInfo().getLocation(); //
OperateStr = "Movemouse,"+point.x+","+point.y;
試す {
ソケット = サーバー.accept();
ソケット.setSoTimeout(1000000);
DataOutputStream 出力 =new DataOutputStream(socket.getOutputStream());
出力.write(operateStr.getBytes());
Output.flush(); //出力ストリームをフラッシュし、バッファされたすべての出力バイトを書き出す
Output.close(); // 出力ストリームを閉じてリソースを解放します。
System.out.println("INFO: "+operateStr);
} キャッチ (IOException e) {
System.out.println("接続が停止しました");
Break; //切断時に無線ループを停止する
}
}
}
}
クライアント:
主なプログラム:
次のようにコードをコピーします。
java.util.concurrent.Executorsをインポートします。
com.Tool.OperateMouse をインポートします。
com.Tool.ReceiveImages をインポートします。
パブリック クラス ReceiveBroderCast {
public ExecutorService エグゼクター。
パブリック静的文字列 IP = "202.216.60.9";
public static void main(String[] args)
{
新しいReceiveBroderCast(IP);
}
public ReceiveBroderCast(String IP) {
exector = Executors.newFixedThreadPool(2);
exector.execute(新しい受信イメージ(IP));
exector.execute(新しいOperateMouse(IP));
}
}
スクリーンショット コードを受け取る:
次のようにコード code をコピーします:/*
* 2014 年 11 月 20 日
※このクラスは教師側からマウスを除く画面情報を受け取るために使用します
*socket()を使用します
*/
public class ReceiveImages extends Thread{
パブリック BorderInit フレーム。
public Socket ソケット。
パブリック文字列IP;
public static void main(String[] args){
new ReceiveImages("202.216.60.7").start();
}
publicReceiveImages(文字列IP)
{
フレーム=新しいBorderInit();
this.IP=IP;
}
public void run() {
while(frame.getFlag()){
System.out.println("接続済み"+(System.currentTimeMillis()/1000)%24%60+"秒");
試す {
ソケット = 新しいソケット(IP,8002);
DataInputStream ImgInput = new DataInputStream(socket.getInputStream());
ZipInputStream imgZip = 新しい ZipInputStream(ImgInput);
画像 img = null;
試す{
imgZip.getNextEntry(); //Zip ファイル ストリームの先頭に移動します。
img = ImageIO.read(imgZip); //Zip イメージ ストリーム内のイメージをバイト数に従って読み取ります。
Frame.jlbImg.setIcon(new ImageIcon(img));
フレーム.検証();
}catch (IOException e) {e.printStackTrace();}
試す{
imgZip.close();
} キャッチ (IOException e) {
System.out.println("接続が切断されました");
}
試す {
TimeUnit.MILLISECONDS.sleep(50);//画像受信間隔時間
} catch (InterruptedException つまり) {
ie.printStackTrace();
}
} キャッチ (IOException e) {
e.printStackTrace();
}ついに{
試す {
ソケット.クローズ();
キャッチ (IOException e) {}
}
}
}
}
クラス BorderInit は JFrame を拡張します
{
プライベート静的最終ロングシリアルバージョンUID = 1L;
パブリック JLabel jlbImg;
プライベートブールフラグ。
public boolean getFlag(){
this.flag を返します。
}
publicBorderInit()
{
this.flag=true;
this.jlbImg = 新しい JLabel();
this.setTitle("リモート監視--IP:" + "--トピック:" );
this.setSize(400, 400);
//this.setUndecorated(true);
//this.setAlwaysOnTop(true); //常に手前に表示
this.add(jlbImg);
this.setLocationRelativeTo(null);
this.setExtendedState(Frame.MAXIMIZED_BOTH);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.setVisible(true);
this.validate();
//ウィンドウクローズイベント
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
フラグ = false;
BorderInit.this.dispose();
System.out.println("フォームを閉じました");
System.gc(); //ガベージコレクション
}
});
}
}
マウス情報を受信し、マウスの動きを制御します。
次のようにコードをコピーします。
java.awt.Robotをインポートします。
インポートjava.io.BufferedInputStream;
java.io.BufferedReaderをインポートします。
インポートjava.io.DataInputStream;
インポート java.io.IOException;
java.io.InputStreamをインポートします。
java.net.Socketをインポートします。
インポート javax.swing.JOptionPane;
/*
※生徒側のマウス操作は教師側と同じです。
* このクラスは、マウス情報を受信し、robot.mouseMove() 関数を使用してマウスの動きを制御します。
*/
public class OperateMouse extends Thread{
public static void main(String[] args)
{
new OperateMouse("202.116.60.7").start();
}
private Socket ソケット。
パブリック文字列IP;
プライベート int OPERATE_PORT = 8001;
プライベートロボットロボット。
パブリック OperateMouse(文字列 IP)
{
this.IP = IP;
}
public void run() {
while(true){
試す {
ソケット = 新しいソケット(IP,OPERATE_PORT);
ロボット = 新しいロボット();
//マウスの動きの情報を取得する
DataInputStream dataIn = new DataInputStream(socket.getInputStream());
文字列情報 = "";
整数r;
while((r=dataIn.read()) != -1){
info +=""+(char)r; //バイト配列内のすべての要素を文字型に変換します。
}
dataIn.close();
System.out.println("データ フローが切断されました"+info);
if(info!=null){
文字列 s[] = info.trim().split(",");
if("Movemouse".equals(s[0].trim()));
{
if (s.length == 3) {
int x = Integer.parseInt(s[1].trim());
int y = Integer.parseInt(s[2].trim());
System.out.println("マウス情報を出力"+x+" "+ y);
robot.mouseMove(x, y);
}
}
}
} キャッチ (IOException e) {
System.out.println("切断されました");
壊す;
キャッチ (AWTException e) {
e.printStackTrace();
}
}
}
}
この記事が皆さんの Java プログラミングに役立つことを願っています。