【问题标题】:Two way communication between a GUI and a Server ClientGUI 和服务器客户端之间的两种方式通信
【发布时间】:2014-04-13 20:12:35
【问题描述】:

我正在尝试在我的 GUI 中按下按钮时发送某个字符串。我的客户端类当前正在运行,以继续从命令行获取字符串命令并将它们发送到服务器,在那里它们将被处理并返回响应。

我现在如何通过我的 GUI 发送数据并将结果移回我的 GUI?

例如我有一个名为“pickup”的按钮,单击该按钮时会通过 Client 类将字符串“PICKUP”发送到服务器。

同样,来自服务器的响应将是“SUCCESS”或“FAIL”,这将通过我的客户端类中的线程“serverResponse”打印出来,并且需要以某种方式发送到 playerGUI 类中的任意方法一个参数。

感谢您的帮助,很抱歉没有使用传统的类/方法/字段命名样式!

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

    }
}

这是客户端类,线程是我想将响应发送到 GUI 类以处理和显示特定输出的地方。星号是我想从 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);
        }   
    }
}

【问题讨论】:

    标签: java user-interface client-server


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      要将数据从 GUI 传递到客户端线程,请使用 LinkedBlockingQueue。要将响应发送到 GUI,请使用 SwingUtilities.invokeLater

      【讨论】:

        【解决方案3】:

        您正在混合服务器端和客户端代码,如下所示。客户端-服务器应用程序不能以这种方式工作。

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

        最终,这两个类都将存在于不同机器上的不同 JVM 中。

        它可能在单台机器上工作,但是如果服务器在一个系统上运行并且多个客户端试图从不同的系统进行通信会发生什么?

        我已经发布了一些示例,请查看Client-Server Communication。我已经逐步描述了它,只需按照线程查找其他示例。

        如果您还有任何问题,请告诉我!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-13
          • 1970-01-01
          • 1970-01-01
          • 2013-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-21
          相关资源
          最近更新 更多