为什么我的构造函数被调用了两次

时间:2014-05-28 03:21:08

标签: java multithreading client

我正在创建一个多线程客户端服务器程序。

有一个客户端登录JPanel,通过将用户名和密码发送到服务器进行检查来验证用户,服务器将发送回客户端:"是"如果正确

if (UsernameandPasswordMatch.equals("Yes"))
  {
       String numofplayers = Utility.ReadFromServer();
       int numofplayer_int = Integer.parseInt(numofplayers);
       new GameTablePanel(numofplayer_int).start(numofplayer_int);

       //change to game table panel 
   }

这是GameTablePanel类的开始方法

void start(int numofplayer_int)
    {
        JLayeredPane lpane = new JLayeredPane();
        lpane.setBounds(0, 0, 1200, 750);

        JPanel background = new WallPaper();
        //background.setBounds(0, 0, 1200, 750);
        background.setOpaque(true);

    GameTablePanel panel = new GameTablePanel(numofplayer_int); //called 2nd time
        //panel.setBounds(100, 100, 400, 400);
        panel.setBounds(0,0,1200,750);
        panel.setOpaque(false);

        lpane.add(background, new Integer(0), 0);
        lpane.add(panel, new Integer(1), 0);

        Utility.ChangeJLPanel(lpane);

    }

使用调试器,我意识到一旦我进入start方法就立即调用Constructor,当我到达

时再次调用
  

GameTablePanel panel = new GameTablePanel(numofplayer_int)

仅供参考:每次客户端连接到服务器时,我都会在服务器端创建一个新线程

如何仅在ONCE中调用我的构造函数而不是两次

3 个答案:

答案 0 :(得分:3)

似乎你明确地两次调用它,一次从这里开始

new GameTablePanel(numofplayer_int).start(numofplayer_int);

再次从GametablePanel的start方法内部开始。那是你要的吗?我不熟悉你要做的事情,但由于你的启动方法已经属于那个面板,你可能会这样做:

void start(int numofplayer_int) {
        JLayeredPane lpane = new JLayeredPane();
        lpane.setBounds(0, 0, 1200, 750);

        JPanel background = new WallPaper();
        //background.setBounds(0, 0, 1200, 750);
        background.setOpaque(true);

        //this.setBounds(100, 100, 400, 400);
        this.setBounds(0,0,1200,750);
        this.setOpaque(false);

        lpane.add(background, new Integer(0), 0);
        lpane.add(this, new Integer(1), 0);

        Utility.ChangeJLPanel(lpane);
}

答案 1 :(得分:1)

我不确定您的期望,但 实例化了两个GameTablePanel。每次在它前面使用new时,都会调用它的构造函数。每次你这样做,你会得到一个不同的类的实例引用(但你第一次扔掉一个)。在您的代码中,当密码匹配时,您首次实例化GameTablePanel

new GameTablePanel(numofplayer_int).start(numofplayer_int);
^

然后再次进入start()

GameTablePanel panel = new GameTablePanel(numofplayer_int);
                       ^

您似乎正在寻找一种方法来引用您在start()内首次创建的类的实例。您只需使用this关键字即可:

void start() // don't need the parameter anymore
{
    JLayeredPane lpane = new JLayeredPane();
    lpane.setBounds(0, 0, 1200, 750);

    JPanel background = new WallPaper();
    //background.setBounds(0, 0, 1200, 750);
    background.setOpaque(true);

    // Update self
    //this.setBounds(100, 100, 400, 400);
    this.setBounds(0,0,1200,750);
    this.setOpaque(false);

    lpane.add(background, new Integer(0), 0);
    lpane.add(this, new Integer(1), 0);

    Utility.ChangeJLPanel(lpane);
}

答案 2 :(得分:0)

更改行:
new GameTablePanel(numofplayer_int).start(numofplayer_int);


new GameTablePanel(numofplayer_int).start();

由于您已使用构造函数中的参数初始化它,因此不需要它。

在开始时你已经拥有了GameTablePanel的一个实例,所以不要创建一个新实例,只需使用“this”:

    //panel.setBounds(100, 100, 400, 400);
    this.setBounds(0,0,1200,750);
    this.setOpaque(false);

    lpane.add(background, new Integer(0), 0);
    lpane.add(this, new Integer(1), 0);

    Utility.ChangeJLPanel(lpane);