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

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();试试

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月5日
  • 已采纳回答 7月28日
  • 修改了问题 7月27日
  • 创建了问题 7月27日

悬赏问题

  • ¥15 在若依框架下实现人脸识别
  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同