代码意图:输出端界面监听键盘,通过监听键的按下情况,设定图片的移动方向。将图片的位置属性等封装进一个对象中,再通过对象流进行传输,使图片在输出端同步在相同位置画出。
存在的问题:1、接收到的对象的坐标值,没有随输出端传输过来的对象的坐标值变化而变化。
2、输出端界面没有刷新,每次坐标变化后,在界面上形成类似残影的效果,即在原图上覆盖绘图。
接收端代码:
package views;
import icons.Zi;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class InputView extends JFrame {
ServerSocket ss;
Socket s;
ObjectInputStream ois;
Zi zi;
public void launch() throws IOException, ClassNotFoundException {
//流创建
ss = new ServerSocket(55555);
s = ss.accept();
ois = new ObjectInputStream(s.getInputStream());
System.out.println("输入流创建完成");
zi = (Zi) ois.readObject();
System.out.println("launch读取对象成功");
//界面属性
setVisible(true);
setLayout(null);
setTitle("输入界面");
setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
System.out.println("启动输入界面刷新线程");
new Thread(new InputView.PaintThread()).start();
}
@Override
public void paint(Graphics g) {
zi.paint(g);
}
private Image offScreenImage = null;
@Override
public void update(Graphics g) {
if(offScreenImage == null) {
offScreenImage = this.createImage(800, 600);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.LIGHT_GRAY);
gOffScreen.fillRect(0, 0, 800, 600);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
class PaintThread implements Runnable{
@Override
public void run() {
System.out.println("进入输入界面线程");
while(true) {
try {
System.out.println("读取对象");
zi = (Zi) ois.readObject();
System.out.println("线程读取对象成功");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
repaint();
System.out.println(zi.getX() + " " + zi.getY());
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
InputView iv = new InputView();
iv.launch();
}
}
发送端代码
package views;
import icons.Zi;
import inputListeners.OutputListeners;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class OutputView extends JFrame {
Socket s;
ObjectOutputStream oos;
Zi zi = Zi.getZi();
public void launch() throws IOException {
//流创建
s = new Socket("127.0.0.1", 55555);
oos = new ObjectOutputStream(s.getOutputStream());
System.out.println("输出流创建完毕");
oos.writeObject(zi);
//界面属性
setVisible(true);
setLayout(null);
setTitle("输出界面");
setSize(800, 600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addKeyListener(new OutputListeners(zi));
System.out.println("启动输出界面刷新线程");
new Thread(new PaintThread()).start();
}
@Override
public void paint(Graphics g) {
zi.paint(g);
}
private Image offScreenImage = null;
@Override
public void update(Graphics g) {
if(offScreenImage == null) {
offScreenImage = this.createImage(800, 600);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.LIGHT_GRAY);
gOffScreen.fillRect(0, 0, 800, 600);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
class PaintThread implements Runnable{
@Override
public void run() {
System.out.println("进入输出界面线程");
while (true) {
repaint();
System.out.println(zi.getX() + " " + zi.getY());
try {
System.out.println("输出对象");
oos.writeObject(zi);
oos.flush();
System.out.println("线程写对象成功");
} catch (IOException e) {
e.printStackTrace();
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws IOException {
OutputView ov = new OutputView();
ov.launch();
}
}
输出端监听器
package inputListeners;
import icons.Dir;
import icons.Zi;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class OutputListeners extends KeyAdapter {
private Zi zi;
public OutputListeners(Zi zi) {
this.zi = zi;
}
private boolean w = false;
private boolean a = false;
private boolean s = false;
private boolean d = false;
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case 65: a = true;break;
case 68: d = true;break;
case 87: w = true;break;
case 83: s = true;break;
}
setDir(w, a, s, d);
}
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case 65: a = false;break;
case 68: d = false;break;
case 87: w = false;break;
case 83: s = false;break;
}
setDir(w, a, s, d);
}
//根据键盘按下情况,设定图片移动方向
private void setDir(boolean w, boolean a, boolean s, boolean d) {
if (w && !a && !s && !d) zi.setDir(Dir.UP);
if (!w && a && !s && !d) zi.setDir(Dir.LEFT);
if (!w && !a && s && !d) zi.setDir(Dir.DOWN);
if (!w && !a && !s && d) zi.setDir(Dir.RIGHT);
if (w && a && !s && !d) zi.setDir(Dir.UP_LEFT);
if (w && !a && !s && d) zi.setDir(Dir.UP_RIGHT);
if (!w && a && s && !d) zi.setDir(Dir.DOWN_LEFT);
if (!w && !a && s && d) zi.setDir(Dir.DOWN_RIGHT);
if (!w && !a && !s && !d) zi.setDir(Dir.STATIC);
zi.move();
}
}
Zi类
package icons;
import java.awt.*;
import java.io.Serial;
import java.io.Serializable;
public class Zi implements Serializable {
int x = 50, y = 50;
Dir dir = Dir.STATIC;
final int SPEED = 20;
@Serial
private static final long serialVersionUID = -5809782578272943999L;
private Zi() { }
private static Zi zi = new Zi();
public void paint(Graphics g) {
g.drawImage(ResourceLoader.icon, x, y, 50, 50, null);
}
public void setDir(Dir dir) { this.dir = dir; }
public static Zi getZi() { return zi; }
public int getX() { return x; }
public int getY() { return y; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
//通过方向信息,设定坐标变化
public void move() {
if (zi.dir == Dir.UP) {
y -= SPEED;
} else if (zi.dir == Dir.DOWN) {
y += SPEED;
} else if (zi.dir == Dir.LEFT) {
x -= SPEED;
} else if (zi.dir == Dir.RIGHT) {
x += SPEED;
} else if (zi.dir == Dir.UP_LEFT) {
x -= SPEED;
y -= SPEED;
} else if (zi.dir == Dir.UP_RIGHT) {
x += SPEED;
y += SPEED;
} else if (zi.dir == Dir.DOWN_LEFT) {
x -= SPEED;
y += SPEED;
} else if (zi.dir == Dir.DOWN_RIGHT) {
x += SPEED;
y += SPEED;
}
zi.setX(x);
zi.setY(y);
}
}
载入一张图的Resourceloader类
package icons;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.IOException;
import java.util.Objects;
public class ResourceLoader {
static Image icon;
static {
try {
icon = ImageIO.read(Objects.requireNonNull(ClassLoader.getSystemResourceAsStream ("portrait1.png")));
} catch (IOException e) {
e.printStackTrace();
}
}
}
枚举类变量 方向Dir
package icons;
public enum Dir {
LEFT, RIGHT, UP, DOWN, UP_RIGHT, UP_LEFT, DOWN_RIGHT, DOWN_LEFT, STATIC,
}
以上为完整代码,有点多,我怕叙述不清就都粘过来了
希望能帮我解决一下我在开头说的两个问题