只汝
2021-07-27 23:35
采纳率: 83.3%
浏览 45
已结题

java对象流,传输的对象和接收的对象的内部属性相同么?

代码意图:输出端界面监听键盘,通过监听键的按下情况,设定图片的移动方向。将图片的位置属性等封装进一个对象中,再通过对象流进行传输,使图片在输出端同步在相同位置画出。
存在的问题:1、接收到的对象的坐标值,没有随输出端传输过来的对象的坐标值变化而变化。
2、输出端界面没有刷新,每次坐标变化后,在界面上形成类似残影的效果,即在原图上覆盖绘图。

img

接收端代码:

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,
}

以上为完整代码,有点多,我怕叙述不清就都粘过来了
希望能帮我解决一下我在开头说的两个问题

  • 点赞
  • 收藏

2条回答 默认 最新

  • 已采纳

    你这个用对象流不太合适,因为并没有传输对象,直接用字节数组就可以了;发送数据完成加一条语句,oos. flush();试试

    点赞 打赏 评论
  • qfl_sdu 2021-07-28 00:12

    1.只要你两端的类是一样的,传输的类属性就是一致的。
    2.刷新残影的问题,需要在每次绘制前清空上一次绘制的内容,或者直接全部重绘
    3.接收端接收到数据不更新位置的问题,首先需要确认问题在哪里,是传过来的数据不正确,还是接收端的处理有问题。可以在接收端做个定时器,用定时器模拟数据,看看图片是否更新。

    点赞 打赏 评论

相关推荐 更多相似问题