ตัวอย่างในบทความนี้อธิบายวิธีที่ Java ใช้งานการแพร่ภาพหน้าจอโดยการควบคุมเมาส์ แบ่งปันกับทุกคนสำหรับการอ้างอิงของคุณ การวิเคราะห์เฉพาะมีดังนี้:
ในบทความก่อนหน้านี้ "การวิเคราะห์ตัวอย่างการใช้ฟังก์ชันการแชร์หน้าจอใน Java" กล่าวถึงว่าเมื่อจับภาพหน้าจอจะไม่มีเมาส์ หากต้องการดูเมาส์บนอินเทอร์เฟซของครู คุณสามารถวาดเมาส์ไปยังภาพหน้าจอแต่ละภาพได้เมื่อใด การจับภาพหน้าจอ อย่างไรก็ตาม เนื่องจากภาพหน้าจอถูกถ่ายทีละภาพ เมาส์ที่คุณเห็นจึงติดอยู่เล็กน้อยอย่างหลีกเลี่ยงไม่ได้ ฉันเคยเขียนแอปเพล็ตควบคุมเมาส์ Java มาก่อน และคุณสามารถเห็นการสาธิตเมาส์ในลักษณะนี้
วิธีการนำไปใช้ก็ค่อนข้างง่าย สองบทความก่อนหน้านี้ใช้ฟังก์ชันการควบคุมเมาส์และการแชร์หน้าจอโดยไม่ต้องใช้เมาส์ตามลำดับ เรามาวิเคราะห์ทั้งสองอย่างคร่าวๆ กัน
ทางฝั่งเซิร์ฟเวอร์ SendScreenImg และ SendMouseMessage ถือเป็นคลาสเครื่องมือสองคลาส โดยรับฟังพอร์ตที่แตกต่างกันตามลำดับ ทั้งสองคลาสใช้คลาส Thread และเราใช้คลาสเธรดพูล ExecutorService เพื่อควบคุมคลาสเหล่านั้น
มีการใช้สองพอร์ตเพราะฉันยังไม่รู้ว่าจะส่งข้อมูลเมาส์และข้อมูลรูปภาพเข้าด้วยกันได้อย่างไร บางทีฉันอาจแปลงรูปภาพเป็นอาร์เรย์ไบต์และใส่พิกัดของเมาส์ไว้ด้านหน้าอาร์เรย์ได้ แต่ในกรณีนี้ เมาส์อาจไม่ต่อเนื่องกันเพราะความเร็วในการส่งพิกัดของเมาส์จะเร็วกว่าการส่งรูปภาพ เอาล่ะ ลองอีกครั้งเมื่อคุณมีเวลา
การเปรียบเทียบลูกค้าเหมือนกับข้างต้น
นี่คือรหัส:
เซิร์ฟเวอร์:
โปรแกรมหลัก:
คัดลอกโค้ดโค้ดดังนี้:/*
* คลาสการออกอากาศหน้าจอเรียกคลาสเครื่องมือสองคลาส: คลาสสำหรับการส่งข้อมูลภาพหน้าจอและคลาสสำหรับการส่งข้อมูลเมาส์โดยใช้เธรดพูล
-
BroderCast คลาสสาธารณะ {
โมฆะสาธารณะคง main (String [] args)
-
ใหม่ BroderCast();
System.out.println("เริ่ม");
-
BroderCast สาธารณะ ()
-
ExecutorService exector = Executors.newFixedThreadPool(2);
exector.execute(ใหม่ SendScreenImg());
exector.execute(ใหม่ SendMouseMessage());
-
-
ส่งรหัสภาพหน้าจอ:
คัดลอกโค้ดดังต่อไปนี้: import java.awt.Dimension;
นำเข้า 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 ขยายเธรด
-
เซิร์ฟเวอร์ int สาธารณะ = 8002;
ServerSocket ส่วนตัว serverSocket;
หุ่นยนต์หุ่นยนต์ส่วนตัว
หน้าจอมิติสาธารณะ
สี่เหลี่ยมผืนผ้าสาธารณะ;
ซ็อกเก็ตซ็อกเก็ตส่วนตัว
โมฆะคงสาธารณะหลัก (String args [])
-
ใหม่ SendScreenImg().start();
-
โมฆะสาธารณะ changeServerPort (int serverPort)
-
ถ้า (this.serverPort == serverPort) กลับมา;
พยายาม{
this.serverSocket.close(); //จำเป็นต้องปิดพอร์ตปัจจุบันก่อน
this.serverPort = เซิร์ฟเวอร์พอร์ต;
serverSocket = ServerSocket ใหม่ (this.serverPort);
serverSocket.setSoTimeout (8000000);
}จับ(ข้อยกเว้นจ){}
-
//วิธีการก่อสร้างเพื่อเปิดหุ่นยนต์เชื่อมต่อซ็อกเก็ตและรับขนาดหน้าจอ
SendScreenImg สาธารณะ ()
-
พยายาม {
serverSocket = ServerSocket ใหม่ (getServerPort ());
serverSocket.setSoTimeout(864000000);
หุ่นยนต์ = หุ่นยนต์ใหม่ ();
} จับ (ข้อยกเว้นจ) {
e.printStackTrace();
-
screen = Toolkit.getDefaultToolkit().getScreenSize(); //รับขนาดของหน้าจอหลัก
rect = สี่เหลี่ยมผืนผ้าใหม่ (หน้าจอ); // สร้างสี่เหลี่ยมที่มีขนาดตรงกัน
-
@แทนที่
การรันโมฆะสาธารณะ ()
-
//กำลังรอรับข้อความภาพหน้าจอแบบเรียลไทม์
ในขณะที่ (จริง) {
พยายาม {
ซ็อกเก็ต = serverSocket.accept ();
ZipOutputStream zip = ZipOutputStream ใหม่ (DataOutputStream ใหม่ (socket.getOutputStream()));
zip.setLevel(9); //ตั้งค่าระดับการบีบอัด
พยายาม{
BufferedImage img = robot.createScreenCapture(rect);
zip.putNextEntry(ZipEntry ใหม่("test.jpg"));
ImageIO.write(img, "jpg", zip);
ถ้า(zip!=null)zip.close();
System.out.println("เชื่อมต่อพอร์ตนักเรียนแล้ว");
} จับ (IOException ioe) {
System.out.println("เทอร์มินัลที่ควบคุม: ตัดการเชื่อมต่อ");
-
} จับ (IOException ioe) {
System.out.println("การเชื่อมต่อผิดพลาด");
} ในที่สุด {
ถ้า (ซ็อกเก็ต != null) {
พยายาม {
ซ็อกเก็ต.ปิด();
} จับ (IOException จ) {
-
-
-
-
-
-
ส่งข้อมูลเมาส์:
คัดลอกโค้ดโค้ดดังนี้:/*
* คลาสเครื่องมือ: รับข้อมูลเมาส์และส่งไปยังเทอร์มินัลนักเรียน
-
SendMouseMessage คลาสสาธารณะขยายเธรด {
ส่วนตัว OPERATE_PORT = 8001;
เซิร์ฟเวอร์ ServerSocket ส่วนตัว
ซ็อกเก็ตซ็อกเก็ตส่วนตัว
สตริงส่วนตัวดำเนินการ Str;
โมฆะสาธารณะคง main (String [] args)
-
ใหม่ SendMouseMessage().start();
-
SendMouseMessage สาธารณะ () {
พยายาม {
เซิร์ฟเวอร์ = ServerSocket ใหม่ (OPERATE_PORT);
//JOptionPane.showMessageDialog(null, "เริ่มฟังแล้ว");
} จับ (IOException e1) {
e1.printStackTrace();
-
-
//หลายเธรดตรวจสอบไคลเอนต์ในวงวนไร้สาย
การรันโมฆะสาธารณะ ()
-
ในขณะที่ (จริง) {
จุด point = MouseInfo.getPointerInfo().getLocation();
ดำเนินการStr = "Movemouse"+point.x+","+point.y;
พยายาม {
ซ็อกเก็ต = เซิร์ฟเวอร์ยอมรับ ();
ซ็อกเก็ต setSoTimeout (1000000);
เอาต์พุต DataOutputStream = DataOutputStream ใหม่ (socket.getOutputStream());
เอาท์พุต.เขียน(operateStr.getBytes());
output.flush(); //ล้างกระแสข้อมูลเอาต์พุตและเขียนไบต์เอาต์พุตที่บัฟเฟอร์ทั้งหมด
output.close(); //ปิดกระแสเอาต์พุตและปล่อยทรัพยากร
System.out.println("ข้อมูล: "+operateStr);
} จับ (IOException จ) {
System.out.println("การเชื่อมต่อหยุดลง");
พัง; //หยุดการวนซ้ำไร้สายเมื่อตัดการเชื่อมต่อ
-
-
-
-
ลูกค้า:
โปรแกรมหลัก:
คัดลอกรหัสดังต่อไปนี้: import java.util.concurrent.ExecutorService;
นำเข้า java.util.concurrent.Executors;
นำเข้า com.Tool.OperateMouse;
นำเข้า com.Tool.ReceiveImages;
ReceiverBroderCast คลาสสาธารณะ {
ผู้บริหาร ExecutorService สาธารณะ;
สาธารณะ IP สตริงคงที่ = "202.216.60.9";
โมฆะสาธารณะคง main (String [] args)
-
ใหม่ ReceiverBroderCast(IP);
-
ReceiverBroderCast สาธารณะ (สตริง IP) {
ตัวจัดการ = Executors.newFixedThreadPool (2);
exector.execute (รับรูปภาพใหม่ (IP));
exector.execute (OperateMouse ใหม่ (IP));
-
-
รับรหัสภาพหน้าจอ:
คัดลอกโค้ดโค้ดดังนี้:/*
* 20-11-2557
* คลาสนี้ใช้รับข้อมูลหน้าจอจากฝั่งอาจารย์ ไม่รวมเมาส์
* ใช้ซ็อกเก็ต ()
-
ReceiverImages คลาสสาธารณะขยายเธรด {
เฟรม BorderInit สาธารณะ
ซ็อกเก็ตซ็อกเก็ตสาธารณะ;
IP สตริงสาธารณะ;
โมฆะคงที่สาธารณะ main (String [] args) {
ใหม่ ReceiverImages("202.216.60.7").start();
-
publicReceiveImages (สตริง IP)
-
เฟรม = BorderInit ใหม่ ();
นี้.IP=IP;
-
โมฆะสาธารณะวิ่ง () {
ในขณะที่(frame.getFlag()){
System.out.println("เชื่อมต่อแล้ว"+(System.currentTimeMillis()/1000)%24%60+"วินาที");
พยายาม {
ซ็อกเก็ต = ซ็อกเก็ตใหม่ (IP,8002);
DataInputStream ImgInput = DataInputStream ใหม่ (socket.getInputStream());
ZipInputStream imgZip = ZipInputStream ใหม่ (ImgInput);
รูปภาพ img = null;
พยายาม{
imgZip.getNextEntry(); //ไปที่จุดเริ่มต้นของสตรีมไฟล์ Zip
img = ImageIO.read(imgZip); // อ่านรูปภาพในสตรีมรูปภาพ Zip ตามไบต์
frame.jlbImg.setIcon (ImageIcon ใหม่ (img));
เฟรม.ตรวจสอบ();
} จับ (IOException e) {e.printStackTrace();}
พยายาม{
imgZip.close();
} จับ (IOException จ) {
System.out.println("การเชื่อมต่อถูกตัดการเชื่อมต่อ");
-
พยายาม {
TimeUnit.MILLISECONDS.sleep(50);//ช่วงเวลาในการรับภาพ
} จับ (InterruptedException เช่น) {
เช่น.printStackTrace();
-
} จับ (IOException จ) {
e.printStackTrace();
}ในที่สุด{
พยายาม {
ซ็อกเก็ต.ปิด();
} จับ (IOException e) {}
-
-
-
-
คลาส BorderInit ขยาย JFrame
-
serialVersionUID ยาวสุดท้ายแบบคงที่ส่วนตัว = 1L;
JLabel jlbImg สาธารณะ;
ธงบูลีนส่วนตัว
บูลีนสาธารณะ getFlag(){
กลับ this.flag;
-
สาธารณะBorderInit()
-
นี้.flag=true;
this.jlbImg = JLabel ใหม่ ();
this.setTitle("การตรวจสอบระยะไกล--IP:" + "--หัวข้อ:" );
นี้.setSize(400, 400);
//this.setUndecorated(จริง);
//this.setAlwaysOnTop(จริง); //อยู่ด้านบนเสมอ
this.add(jlbImg);
this.setLocationRelativeTo(null);
this.setEXTENDEDState (เฟรม MAXIMIZED_BOTH);
this.setDefaultCloseOperation (DISPOSE_ON_CLOSE);
this.setVisible (จริง);
นี้.ตรวจสอบ();
//เหตุการณ์ปิดหน้าต่าง
this.addWindowListener (WindowAdapter ใหม่ () {
โมฆะสาธารณะ windowClosing (WindowEvent e) {
ธง=เท็จ;
BorderInit.this.dispose();
System.out.println("ปิดแบบฟอร์มแล้ว");
System.gc(); //รวบรวมขยะ
-
-
-
-
รับข้อมูลเมาส์และควบคุมการเคลื่อนไหวของเมาส์:
คัดลอกรหัสดังต่อไปนี้: นำเข้า java.awt.AWTException;
นำเข้า 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()
-
OperateMouse คลาสสาธารณะขยายเธรด {
โมฆะสาธารณะคง main (String [] args)
-
ใหม่ OperateMouse("202.116.60.7").start();
-
ซ็อกเก็ตซ็อกเก็ตส่วนตัว
IP สตริงสาธารณะ;
ส่วนตัว OPERATE_PORT = 8001;
หุ่นยนต์หุ่นยนต์ส่วนตัว
OperateMouse สาธารณะ (สตริง IP)
-
นี้.IP = IP;
-
โมฆะสาธารณะวิ่ง () {
ในขณะที่ (จริง) {
พยายาม {
ซ็อกเก็ต = ซ็อกเก็ตใหม่ (IP, OPERATE_PORT);
หุ่นยนต์ = หุ่นยนต์ใหม่ ();
//รับข้อมูลการเคลื่อนไหวของเมาส์
DataInputStream dataIn = DataInputStream ใหม่ (socket.getInputStream());
ข้อมูลสตริง = "";
อินท์อาร์;
ในขณะที่((r=dataIn.read()) != -1){
info +=""+(char)r; // แปลงองค์ประกอบทั้งหมดในอาร์เรย์ไบต์เป็นประเภทอักขระ
-
ข้อมูลIn.close();
System.out.println("กระแสข้อมูลถูกตัดการเชื่อมต่อ"+ข้อมูล);
ถ้า(ข้อมูล!=null){
สตริง s[] = info.trim().split(",");
if("Movemouse".เท่ากับ(s[0].trim()));
-
ถ้า (ความยาว == 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 จ) {
System.out.println("ตัดการเชื่อมต่อ");
หยุดพัก;
} จับ (AWTException e) {
e.printStackTrace();
-
-
-
-
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม Java ของทุกคน