简体   繁体   English

GUI和服务器客户端之间的双向通信

[英]Two way communication between a GUI and a Server Client

I'm trying to send a certain string when a button is pressed in my GUI. 当我在GUI中按下按钮时,我试图发送某个字符串。 My Client class is currently running to keep taking string commands from the command line and send them to the server where they will be processed and a response will be returned. 我的Client类当前正在运行,以继续从命令行获取字符串命令,并将其发送到服务器,在此将对其进行处理并返回响应。

How can I now send the data through my GUI and move the results back to my GUI? 现在如何通过GUI发送数据并将结果移回GUI?

Eg I have a button called "pickup" which, when clicked will send the string "PICKUP" to the server, through the Client class. 例如,我有一个名为“ pickup”的按钮,当单击该按钮时,它将通过Client类将字符串“ PICKUP”发送到服务器。

Likewise, the response from the server would be either "SUCCESS" or "FAIL" which would be printed through the Thread "serverResponse" in my Client class and this needs to somehow be sent to an arbitrary method in the playerGUI class as a parameter. 同样,来自服务器的响应将是“ SUCCESS”或“ FAIL”,这将通过我的Client类中的线程“ serverResponse”打印出来,并且需要以某种方式将其发送到playerGUI类中的任意方法作为参数。

Thanks for any help, sorry for not using the conventional class/method/field naming styles! 感谢您的帮助,对于未使用常规的类/方法/字段命名样式感到抱歉!

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

public class playerGUI {
    private JFrame frame = new JFrame();
    private JPanel displayPanel;
    private JTextPane hostTextPane;
    private JTextPane portTextPane;
    private static Client newclient;

    public static void main(String[] args) {
        playerGUI GUI = new playerGUI();
        GUI.frame.setVisible(true);
        newclient = new Client(GUI);
    }

    /**
     * Create the application.
     */
    public playerGUI() {
        frame.getContentPane().setBackground(new Color(255, 255, 255));
        frame.getContentPane().setLayout(null);
        frame.setBounds(100, 100, 500, 630);
        frame.setUndecorated(false); // REMOVES MENU BAR
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        final JPanel humanGameWindow = new JPanel();
        humanGameWindow.setLayout(null);
        humanGameWindow.setBackground(Color.LIGHT_GRAY);
        humanGameWindow.setBounds(0, 0, 500, 630);
        humanGameWindow.setVisible(false);

        JButton pickup = new JButton("Pickup");
        pickup.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //I WANT TO SEND THE STRING "PICKUP" TO WHERE THE STARS ARE IN Client.class
            }
        });
        pickup.setBackground(new Color(100, 149, 237));
        pickup.setBounds(40, 555, 100, 40);

        displayPanel = new JPanel();
        displayPanel.setBounds(48, 89, 400, 400);
        displayPanel.setLayout(new GridLayout(5, 5));
        displayPanel.setPreferredSize(new Dimension((int) (400), (int) (400)));
        for (int i = 1; i < 26; i++) {
            displayPanel.add(new JLabel("Label " + i));
        }

        JButton Look = new JButton("Look");
        Look.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

            }
        });
        Look.setBackground(new Color(100, 149, 237));
        Look.setBounds(40, 514, 100, 40);

        humanGameWindow.add(Look);
        humanGameWindow.add(pickup);
        humanGameWindow.add(displayPanel);

        final JPanel mainMenu = new JPanel();
        mainMenu.setLayout(null);
        mainMenu.setBackground(Color.DARK_GRAY);
        mainMenu.setBounds(0, 0, 500, 630);
        mainMenu.setVisible(true);

        JLabel mainMenuTitle = new JLabel("DUNGEON OF DOOM!!");
        mainMenuTitle.setForeground(new Color(100, 149, 237));
        mainMenuTitle.setFont(new Font("Moire", Font.BOLD, 28));
        mainMenuTitle.setBounds(50, 13, 380, 50);

        JButton mainMenuQuit = new JButton("Quit");
        mainMenuQuit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        mainMenuQuit.setBackground(new Color(100, 149, 237));
        mainMenuQuit.setBounds(220, 345, 70, 55);

        JButton playGameHuman = new JButton("Play Game Human");
        playGameHuman.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                mainMenu.setVisible(false);
                humanGameWindow.setVisible(true);
            }
        });
        playGameHuman.setBackground(new Color(100, 149, 237));
        playGameHuman.setBounds(50, 345, 150, 55);

        mainMenu.add(mainMenuTitle);
        mainMenu.add(mainMenuQuit);
        mainMenu.add(playGameHuman);

        frame.getContentPane().add(humanGameWindow);
        frame.getContentPane().add(mainMenu);
        frame.setVisible(true);

    }
}

This is the Client class, the thread is where I want to send the response to the GUI class to process and display a specific output. 这是Client类,线程是我想要将响应发送到GUI类以处理和显示特定输出的地方。 The asterisks is where I want to send the text from button presses in the GUI class (there are other buttons I have deleted the code for easier reading!). 星号是我要从GUI类中的按钮发送文本的地方(还有其他按钮,我已删除了代码,以方便阅读!)。

import java.net.*;
import java.io.*;

public class Client{
    public Client(playerGUI GUI){   
        try{
            final Socket sock = new Socket("localhost",4444);
            final DataInputStream in = new DataInputStream(sock.getInputStream());
            final PrintStream out = new PrintStream(sock.getOutputStream());
            DataInputStream inputLine = new DataInputStream(new BufferedInputStream(System.in));

            final Thread serverResponse = new Thread(){
                public void run(){
                    System.out.println("DUNGEON OF DOOM HAS STARTED");
                    if(sock != null){
                        if(in != null){
                            try{
                                String response;
                                while((response = in.readLine()) != null){
                                    //I WANT TO SEND "response" TO THE GUI CLASS
                                    System.out.println(response);
                                }
                            }catch(UnknownHostException uhe){
                                System.err.println("Unknown host1: " + uhe);
                            }catch(IOException ioe){
                                System.err.println("IOException1: " + ioe);
                            }catch(NullPointerException npe){
                                System.err.println("Null Pointer1: " + npe);
                            }
                        }
                    }
                }
            };
            serverResponse.start();
            if(sock != null){
                if(out != null){
                    try{
                        while(true){
                            String sending = *************************
                            //String sending = inputLine.readLine(); 
                            out.println(sending);
                            if(sending.equals("QUIT")) break;
                        }
                    }catch(UnknownHostException uhe2){
                        System.err.println("Unknown host2: " + uhe2);
                    }catch(IOException ioe2){
                        System.err.println("IOException2: " + ioe2);
                    }catch(NullPointerException npe2){
                        System.err.println("Null Pointer2: " + npe2);
                    }
                }
            }
            out.close();
            in.close();
            sock.close();
        }catch(UnknownHostException uhe3){
            System.err.println("Unknown host3: " + uhe3);
        }catch(IOException ioe3){
            System.err.println("IOException3: " + ioe3);
        }catch(NullPointerException npe3){
            System.err.println("Null Pointer3: " + npe3);
        }   
    }
}

您可能应该阅读该内容,然后提出问题: 教程

To pass data from GUI to client thread, use LinkedBlockingQueue . 要将数据从GUI传递到客户端线程,请使用LinkedBlockingQueue To send the response to the GUI, use SwingUtilities.invokeLater . 要将响应发送到GUI,请使用SwingUtilities.invokeLater

You are mixing server and client side code as shown below. 您正在混合服务器和客户端代码,如下所示。 Client-Server application doesn't work in this way. 客户端-服务器应用程序无法以这种方式工作。

public static void main(String[] args) {
    playerGUI GUI = new playerGUI();
    GUI.frame.setVisible(true);
    newclient = new Client(GUI);
}

In the final both the classes will live in separate JVM on separate Machine. 最后,这两个类都将驻留在单独计算机上的单独JVM中。

It might work on single machine but What will happen if server is running on one system and multiple clients are trying to communicate from different systems? 它可能在单台机器上工作,但是如果服务器在一个系统上运行并且多个客户端试图从不同的系统进行通信,将会发生什么?

I have already posted some samples, please have a look at Client-Server Communication . 我已经发布了一些示例,请查看客户端-服务器通信 I have described it step by step just follow the thread to find other samples as well. 我已经一步一步地描述了它,只是按照线程来查找其他样本。

Please let me know if still you have any issue! 如果您还有任何问题,请告诉我!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM