有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用socket将JFrame图形从客户端发送到服务器

我正在尝试发送我的java文件,其中有一个JFrame绘图,带有按钮,可以将背景颜色从客户端更改为服务器。服务器接收该图形并打开它,但当我单击按钮时,没有任何更改。我做错了什么?此外,由于某些原因,该应用程序有时无法运行

按图纸编码

package Drawings;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.*;

public class DrawingTwo extends JFrame {


    public static final int DEFAULT_WIDTH = 300;
    public static final int DEFAULT_HEIGHT = 300;

    public Color tvColor;
    public Color smileColor;
    public int h;
    public int h2;
    public int h3;
    public int h4;
    public int h5;
    public int h6;
    public String l;
    public DrawComponent c;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DrawingTwo();
            }
        });

    }

    public DrawingTwo() {
        super();
        setOneChanell();

        Container container = getContentPane();
        container.setBackground(new Color(242, 212, 252));
        container.setLayout(new BorderLayout(20, 20));
        container.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));

        ButtonListener listener = new ButtonListener();

        JLabel lb = new JLabel(l);
        lb.setText(l);
        container.add(lb);
        JButton j2 = new JButton("2");
        j2.addActionListener(listener);
        container.add(j2, BorderLayout.NORTH);

        c = new DrawComponent();
        container.add(c, BorderLayout.CENTER);

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public void setOneChanell() {
        this.tvColor = new Color(255, 153, 153);
        this.smileColor = new Color(255, 247, 10);
        this.h = 110;
        this.h2 = 55;
        this.h3 = 60;
        this.h4 = 60;
        this.h5 = 0;
        this.h6 = -180;
        this.l = "Канал для веселых";
    }

    public void setTwoChanell() {
        this.tvColor = new Color(172, 194, 157);
        this.smileColor = new Color(0, 161, 219);
        this.h = 115;
        this.h2 = 87;
        this.h3 = 50;
        this.h4 = 40;
        this.h5 = 0;
        this.h6 = +180;
        this.l = "Канал для грустных";
    }

    public class DrawComponent extends JComponent {

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.black);
            g.fillRect(37, 26, 210, 130);

            g.setColor(tvColor);
            g.fillRect(42, 30, 200, 120);

            g.setColor(Color.darkGray);
            g.fillRect(135, 156, 15, 20);

            g.setColor(Color.darkGray);
            g.fillRect(83, 170, 120, 13);


            g.setColor(smileColor);
            g.fillOval(100, 45, 80, 80);


            g.setColor(Color.BLACK);
            g.drawArc(120, 70, 10, 10, 0, 360);
            g.drawArc(150, 70, 10, 10, 0, 360);

            g.drawString(l, 83, 200);
            g.setColor(Color.BLACK);
            g.drawArc(h, h2, h3, h4, h5, h6);
        }

    }

    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            JButton button = (JButton) event.getSource();
            if (button.getText().equals("2")) {
                setTwoChanell();
                button.setText("1");

            } else {
                setOneChanell();
                button.setText("2");
            }
            c.repaint();
        }

    }

}


这是客户端文件

package ClientToServer;

import java.io.*;

import java.net.Socket;

import Drawings.DrawingTwo;


public class Client {

    public static void main(String[] args) throws IOException {

        Socket socket = new Socket("localhost", 12345);
        OutputStream outputStream = socket.getOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(new DrawingTwo());
        objectOutputStream.flush();
        objectOutputStream.close();
    }


}

这是服务器文件

package ClientToServer;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

import Drawings.DrawingTwo;

import javax.swing.*;

public class Server {



    public static void main(String[] args) throws IOException, ClassNotFoundException {

        ServerSocket serverSocket = new ServerSocket(12345);
        Socket client = serverSocket.accept();
        ObjectInputStream inputStream = new ObjectInputStream(client.getInputStream());

        DrawingTwo object = (DrawingTwo) inputStream.readObject();
        object.setVisible(true);
        object.setTitle("Server");
        object.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        client.close();
        inputStream.close();
        serverSocket.close();
    }
}

共 (1) 个答案

  1. # 1 楼答案

    我建议您多读一些关于套接字通信的内容。如果您有一个服务器套接字,它应该一直运行。在您的代码中,您在从客户端接收数据后立即关闭套接字连接

    另一件事是;您仅使用一种类型限制了通信:DrawingTwo()类。在服务器端,您无法接收任何其他数据

    让我们一步一步地看一下你的代码。

    必须为通信目的定义新对象

    import java.io.Serializable;
    
    public class CommunicationObject implements Serializable{
        
        private DrawingTwo mDrawingTwo;
        private boolean mSmileyFace = true;
        private boolean mIsInitialConnection = true;
        
        
        public DrawingTwo getmDrawingTwo() {
            return mDrawingTwo;
        }
        public void setmDrawingTwo(DrawingTwo mDrawingTwo) {
            this.mDrawingTwo = mDrawingTwo;
        }
        public boolean ismSmileyFace() {
            return mSmileyFace;
        }
        public void setmSmileyFace(boolean mSmileyFace) {
            this.mSmileyFace = mSmileyFace;
        }
        public boolean ismIsInitialConnection() {
            return mIsInitialConnection;
        }
        public void setmIsInitialConnection(boolean mIsInitialConnection) {
            this.mIsInitialConnection = mIsInitialConnection;
        }   
    }
    

    这里有3个字段

    1. 绘图2;你的实际布局是什么
    2. 布尔笑脸;指示按钮的位置
    3. 布尔初始连接;决定是初始化,以便服务器初始化布局还是更改笑脸

    您的服务器必须一直监听

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    import javax.swing.JFrame;
    
    public class Server {
    
        static boolean isRunning = true;
    
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ServerSocket serverSocket = new ServerSocket(12345);
            Socket client = null;
            ObjectInputStream inputStream = null;
            InputStream is = null;
            DrawingTwo drawingTwo = null;
            CommunicationObject communicationObject = null;
    
            while (isRunning) {
                client = serverSocket.accept();
                inputStream = new ObjectInputStream(client.getInputStream());
    
                is = client.getInputStream();
    
                communicationObject = (CommunicationObject) inputStream.readObject();
    
                if (communicationObject.ismIsInitialConnection()) {
                    drawingTwo = (DrawingTwo) communicationObject.getmDrawingTwo();
                    drawingTwo.setVisible(true);
                    drawingTwo.setTitle("Server");
                    drawingTwo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                } else {                
    
                    if (communicationObject.ismSmileyFace()) {
                        drawingTwo.setOneChanell();                     
                    } else {
                        drawingTwo.setTwoChanell();                     
                    }
                    drawingTwo.c.repaint();
    
                }
    
            }
            client.close();
            inputStream.close();
            serverSocket.close();
        }
    }
    

    请注意,isRunning现在总是正确的。您必须处理异常和其他情况才能停止或重新启动它

    为绘图中的JButton创建一个getter两个类

    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.WindowConstants;
    
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Rectangle2D;
    import java.beans.PropertyChangeListener;
    
    public class DrawingTwo extends JFrame{
    
          public static final int DEFAULT_WIDTH = 300;
            public static final int DEFAULT_HEIGHT = 300;
    
            public Color tvColor;
            public Color smileColor;
            public int h;
            public int h2;
            public int h3;
            public int h4;
            public int h5;
            public int h6;
            public String l;
            public DrawComponent c;
            
            
            private JButton j2;
            
            public static void main(String[] args) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        new DrawingTwo();
                    }
                });
    
            }
            
            public DrawingTwo() {
                super();
                setOneChanell();
    
                Container container = getContentPane();
                container.setBackground(new Color(242, 212, 252));
                container.setLayout(new BorderLayout(20, 20));
                container.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
    
                ButtonListener listener = new ButtonListener();
    
                JLabel lb = new JLabel(l);
                lb.setText(l);
                container.add(lb);
                j2 = new JButton("2");
                j2.addActionListener(listener);
                container.add(j2, BorderLayout.NORTH);
    
                c = new DrawComponent();
                container.add(c, BorderLayout.CENTER);
    
                setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                pack();
                setVisible(true);
                            
               
            }
            
            public void setOneChanell() {
                this.tvColor = new Color(255, 153, 153);
                this.smileColor = new Color(255, 247, 10);
                this.h = 110;
                this.h2 = 55;
                this.h3 = 60;
                this.h4 = 60;
                this.h5 = 0;
                this.h6 = -180;
                this.l = "1";
            }
    
            public void setTwoChanell() {
                this.tvColor = new Color(172, 194, 157);
                this.smileColor = new Color(0, 161, 219);
                this.h = 115;
                this.h2 = 87;
                this.h3 = 50;
                this.h4 = 40;
                this.h5 = 0;
                this.h6 = +180;
                this.l = "2";
            }
                    
            public JButton getJButton() {
                return j2;
            }
    
    
            public class DrawComponent extends JComponent {
                
                @Override
                public void paintComponent(Graphics g) {
                    super.paintComponent(g);
                    g.setColor(Color.black);
                    g.fillRect(37, 26, 210, 130);
    
                    g.setColor(tvColor);
                    g.fillRect(42, 30, 200, 120);
    
                    g.setColor(Color.darkGray);
                    g.fillRect(135, 156, 15, 20);
    
                    g.setColor(Color.darkGray);
                    g.fillRect(83, 170, 120, 13);
    
    
                    g.setColor(smileColor);
                    g.fillOval(100, 45, 80, 80);
    
    
                    g.setColor(Color.BLACK);
                    g.drawArc(120, 70, 10, 10, 0, 360);
                    g.drawArc(150, 70, 10, 10, 0, 360);
    
                    g.drawString(l, 83, 200);
                    g.setColor(Color.BLACK);
                    g.drawArc(h, h2, h3, h4, h5, h6);
                }
    
            }
            
            public class ButtonListener implements ActionListener {
    
                @Override
                public void actionPerformed(ActionEvent event) {
                    JButton button = (JButton) event.getSource();
                    if (button.getText().equals("2")) {
                        setTwoChanell();
                        button.setText("1");
    
                    } else {
                        setOneChanell();
                        button.setText("2");
                    }
                    c.repaint();
                }
    
            }
    }
    

    请记住,您的按钮有两个功能

    1. 更改已处理的客户端布局
    2. 将信号发送到您的服务器,以便它也可以更改它

    最后,客户端类

    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import javax.swing.JButton;
    
    public class Client {
        
        static OutputStream outputStream;
        static ObjectOutputStream objectOutputStream;
        static Socket socket;    
        
        public static void main(String[] args) throws UnknownHostException, IOException {
            
            DrawingTwo drawingTwo = new DrawingTwo();
            
            CommunicationObject communicationObject = new CommunicationObject();        
            communicationObject.setmDrawingTwo(drawingTwo);
            communicationObject.setmIsInitialConnection(true);
            
            write(communicationObject);
                    
            JButton button = drawingTwo.getJButton();
            
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
    
                    try {
                        if (button.getText().equals("2")) {
                            
                            communicationObject.setmIsInitialConnection(false);
                            communicationObject.setmSmileyFace(false);
                            write(communicationObject);
                        } else {
                            communicationObject.setmIsInitialConnection(false);
                            communicationObject.setmSmileyFace(true);
                            write(communicationObject);
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                }
            });
        }
        
        
        public static void write(CommunicationObject comObject) throws IOException
        {       
            socket = new Socket("localhost", 12345);
            
            outputStream = socket.getOutputStream();
            objectOutputStream = new ObjectOutputStream(outputStream);
                    
            objectOutputStream.writeObject(comObject);
            
            objectOutputStream.flush();     
            objectOutputStream.close();
        }   
    }
    

    您可以在此处创建一个通信对象,并将DrawingTwo类指定给它

    看看从DrawingTwo中将JButton提取到Client类中的位置,这样就可以将ActionListener绑定到它。现在,您可以通过此操作侦听器与服务器通信

    注意 由于客户端和服务器都可以访问DrawingTwo,所以不需要通过套接字发送整个类。只需向服务器发送一条消息,它应该自己创建一个实例