0

私はこのようにJava sthでやりたい:

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

プログラムは応答を待っています。JFrame (PlayerWindow) を拡張する 1 つのクラスと、JDialog (PlayerLogWindow) を拡張する 2 番目の内部クラスがあります。別のクラス (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

本当に必要なのは、UI をポーリングしようとするのではなく、接続を試みて接続できることを GUI が接続マネージャーに伝える何らかの方法です。これにより、プログラムのさまざまな部分を切断/切り離すことができます。

別のスレッドで「接続」を作成することから始めて、中央ロックを待ちます。これにより、スレッドは通知されるまで待機し、その時点で何をすべきか (試行して接続するかどうか) を決定できます。

メイン UI で、サーバー プロパティを収集したら、接続スレッドを起動するグローバル ロックを通知します。

Javaでの並行性が役に立つかもしれません

于 2013-10-16T20:49:52.270 に答える