0

我想在java中做这样的事情:

http://msdn.microsoft.com/pl-pl/library/c7ykbedk.aspx

程序正在等待回复。我有一个扩展 JFrame (PlayerWindow) 的类,第二个内部类扩展 JDialog (PlayerLogWindow)。另一个类 (Player) 包含 main 方法,需要在 JDialog 类中写入用户参数。使用 while(true) 看起来不正确......也许像模态对话框一样?

public class Player implements Runnable
{
    private Socket socket;
    private String host, nazwa;
    private ObjectOutputStream output;
    private ObjectInputStream input;
    private static int port;

public Player(String host, int port) throws IOException
{
    this.host = host;
    this.port = port;
}

@Override
public void run()
{
    String m1, m2;
    try
    {
        socket = new Socket(host, port);
        input = new ObjectInputStream(socket.getInputStream());
        output = new ObjectOutputStream(socket.getOutputStream());
        output.flush();

        System.out.println("Client's host " + socket.getLocalAddress().getHostName());

        nazwa = Communication.inString("Whats your name: ");
        output.writeObject(nazwa);

        do
        {
            m1 = (String) input.readObject();
            System.out.println("\n" + "Data from server: " + m1);
            m2 = Communication.inString("Write sth to server: ");
            output.writeObject(nazwa + ": " + m2);
        } while (!m2.equals("quit"));

        output.close();
        input.close();
        socket.close();
    } catch (Exception e)
    {
        System.out.println(e);
    }
}

public static void main(String[] args) throws IOException
{
    PlayerWindow playerWindow = new PlayerWindow();     
    String host = InetAddress.getLocalHost().getHostName();

    while(true)
    {
        port = playerWindow.port;

        if (playerWindow.port != 0)
        {
            ShipServer server = new ShipServer(port, host);
            Thread threadServer = new Thread(server);
            threadServer.start();
            break;
        }
    }           
}

}

public class PlayerWindow extends JFrame
{
    private PlayerLogWindow playerLog;  
    int port;

//GUI
private JMenuBar jMenuBar;
private JMenu jMenuFile, jMenuHelp; 
private JMenuItem jMenuItemNewGame, jMenuItemExitGame, jMenuAbout;

public PlayerWindow()
{
    createWindow();

    createJMenu();
}

private void createWindow()
{
    setTitle("Game");
    setUndecorated(true);
    getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Toolkit t = getToolkit();
    Dimension dim = t.getScreenSize();
    setLocation(dim.width/2-400, dim.height/2-400);

    pack(); 
    setSize(1000, 800);
    setVisible(true);       
}

private void createJMenu()
{
     JMenuBar jMenuBar = new JMenuBar();         
     setJMenuBar(jMenuBar);

     jMenuFile = new JMenu("Start");    
     jMenuFile.setFont(new Font("Sansserif", Font.ROMAN_BASELINE, 18));
     jMenuBar.add(jMenuFile);
     jMenuItemNewGame = new JMenuItem("New game");
     jMenuItemNewGame.setFont(new Font("Sansserif", Font.ROMAN_BASELINE, 18));
     jMenuFile.add(jMenuItemNewGame);
     jMenuFile.addSeparator();
     jMenuItemExitGame = new JMenuItem("End");
     jMenuItemExitGame.setFont(new Font("Sansserif", Font.ROMAN_BASELINE, 18));
     jMenuFile.add(jMenuItemExitGame);

     jMenuHelp = new JMenu("Help");
     jMenuHelp.setFont(new Font("Sansserif", Font.ROMAN_BASELINE, 18));
     jMenuBar.add(jMenuHelp);
     jMenuAbout = new JMenuItem("About...");
     jMenuAbout.setFont(new Font("Sansserif", Font.ROMAN_BASELINE, 18));
     jMenuHelp.add(jMenuAbout);     

     playerWindowActionListener();
}   

public void playerWindowActionListener()
{       
    jMenuItemNewGame.addActionListener(new ActionListener()
    {           
        @Override
        public void actionPerformed(ActionEvent arg0)
        {
            if(playerLog == null)
                playerLog = new PlayerLogWindow();                  

            playerLog.setVisible(true);                         
        }
    });     
}

class PlayerLogWindow extends JDialog
{
    //GUI       
    private JPanel jPanelMain;
    private JButton jButtonConnect;
    private JTextField jTextPort;


    public PlayerLogWindow()
    {
        createWindow();

        createComponents();     
    }

    private void createWindow()
    {
        setTitle("Choose server");
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

        Toolkit t = getToolkit();
        Dimension dim = t.getScreenSize();
        setLocation(dim.width/2-200, dim.height/2-200);

        pack(); 
        setSize(400, 200);          
    }

    public void createComponents()
    {
        jPanelMain = new JPanel(new BorderLayout(5,5));
        JLabel jLabelServer = new JLabel("Connect", JLabel.CENTER);
        jLabelServer.setFont(new Font("Sanserif", Font.BOLD, 16));

        JPanel jPanelPort = new JPanel(new FlowLayout());
        JLabel jLabelPort = new JLabel("Port number", JLabel.CENTER);
        jTextPort = new JTextField(10);
        jPanelPort.add(jLabelPort);
        jPanelPort.add(jTextPort);      

        jButtonConnect = new JButton("Start");      

        jPanelMain.add(jLabelServer, "North");
        jPanelMain.add(jPanelPort);
        jPanelMain.add(jButtonConnect, "South");

        add(jPanelMain);        

        connectUser();              
    }

    public void connectUser()
    {
        jButtonConnect.addActionListener(new ActionListener()
        {           
            @Override
            public void actionPerformed(ActionEvent e)
            {
                port = Integer.parseInt(jTextPort.getText());                   
                dispose();
            }
        });     
    }
}

}

4

1 回答 1

2

您真正需要的是 GUI 以某种方式告诉连接管理器它可以尝试连接,而不是尝试轮询 UI。这允许您断开/解耦程序的不同部分。

首先在单独的线程中创建“连接”,然后等待中央锁。这将导致线程等待直到收到通知,此时它可以决定它应该做什么(尝试连接或不连接)。

在您的主 UI 中,一旦您收集了服务器属性,您将通知全局锁,这将唤醒连接线程

您可能会发现Java中的并发有一些用处

于 2013-10-16T20:49:52.270 回答