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

时间:2014-04-11 15:16:54

标签: java user-interface client-server

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

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

E.g。我有一个名为" pickup"当点击时会发送字符串" PICKUP"到服务器,通过Client类。

同样,来自服务器的响应将是" SUCCESS"或"失败"这将通过Thread" serverResponse"打印出来。在我的Client类中,这需要以某种方式发送到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);

    }
}

这是Client类,该线程是我想将响应发送到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);
        }   
    }
}

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

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

在最后两个类中,它们将位于单独的机器上的单独JVM中。

     

它可能适用于单机但如果服务器在一个系统上运行而多个客户端试图从不同系统进行通信会发生什么?

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

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