【问题标题】:how to stop opening of duplicate window using Smack API in swing?如何在摇摆中使用 Smack API 停止打开重复窗口?
【发布时间】:2011-06-19 23:13:30
【问题描述】:

我有 2 个摇摆课程,它们扩展了 JFrame。两者都在构造函数中有show() 方法。从ClassOne 我打电话给ClassTwo 就像new ClassTwo() 在按钮点击事件上。但是,如果我再次按下按钮,ClassTwo 的新窗口将打开。那么,如果打开了一个 ClassTwo 窗口,如何停止打开 ClassTwo 窗口呢?

编辑

现在这个问题已经解决了,但是现在当我第一次打开 ClassTwo 窗口时,它会显示一个窗口。然后在我再次打开 ClassTwo 窗口时关闭它后,它会打开两个窗口,并且这个计数继续增加。为什么会这样?

编辑 2

我发现这不是摇摆问题,而是来自 Samck API 的 MultiUsreChat 类的问题。所以任何参与过它的人都会帮助我。

ClassOne 中的代码是:

if(!winList.contains(room_jid)){
    new ClassTwo(room_jid,....);
    winList.add(room_jid);
}

在 ClassTwo 中是:

public ClassTwo(....){
......
    this.muc = new MultiUserChat(connection, room_jid);
    if(!muc.isJoined())
        muc.join(this.user_id);      //---- This line opens previously closed window.
.....

    if(!isVisible())
       show();

}

编辑 3

类的构造函数

public ClassOne(){
  JButton btn = new JButton("Open");
  btn.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent e){
       if(!winList.contains(room_jid)){
           new ClassTwo(room_jid,....);
            winList.add(room_jid);
       }
     }
  });
}

【问题讨论】:

    标签: java swing window smack


    【解决方案1】:

    不要让框架在 ClassTwo 构造函数中可见。相反,在 classOne 中保留对 classTwo 的引用,并在单击按钮时使其可见,如下所示:

    //on button click
    if(classTwo == null){
        classTwo = new ClassTwo();
    }
    classTwo.setVisible(true);
    

    还将classTwo的默认关闭操作更改为关闭时隐藏,而不是退出:

    setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
    

    因此,单击按钮的次数并不重要,因为它所做的只是使现有实例可见。它不会创建新实例。

    【讨论】:

    • 这个问题已经解决了,但是现在当我第一次打开 ClassTwo 窗口时,它会显示一个窗口。然后在我再次打开 ClassTwo 窗口时关闭它后,它会打开两个窗口,并且这个计数继续增加。为什么会这样?
    • 您的编辑#2 没有说明您如何打开窗口。我相信您仍在某处创建 ClassTwo 窗口的新实例。只在 ClassOne 的构造函数中创建单个实例,然后在按钮中设置其可见性。 +1 对恶作剧。
    • @Kdansky:我添加了完整的代码部分,我在其中调用了 ClassTwo。以及打开先前关闭的窗口的 ClassTwo。但如果你希望我可以分享我的完整代码。 ???
    • 源代码中缺少:按钮处理程序和 ClassOne 的构造函数。哪两个部分值得关注。
    • @Kdansky:我已经用 classone 的构造函数源更新了我的问题。看一看。 reply me using @Harry so i can get your reply even if i'm not in this question.
    【解决方案2】:

    ClassOne 中,您可以简单地记住您是否使用boolean 打开了一个新的ClassTwo

    //in event handler for the button
    if (!classTwoShown)
    {
      classTwoShown = true;
      new ClassTwo();
    }
    

    您还应该挂钩到第二类的 dispose 事件以重置 classTwoShown 标志。

    【讨论】:

      【解决方案3】:

      尝试使用单例模式

      【讨论】:

      • 你能解释更多吗,因为我不知道单吨模式。
      【解决方案4】:

      它不起作用的原因是您在按钮处理程序中创建了一个新的 ClassTwo 实例,这意味着您每次按下按钮时创建一个新窗口。这应该有效:

      private Map<JButton, ClassTwo> classTwoMap;
      
      public ClassOne(){
        classTwoMap = new HashMap<JButton, ClassTwo>();
        ClassTwo bn1window = new ClassTwo();
        bn1window .setVisible(false);
        //initialisation code for your window
        .....
        JButton btn = new JButton("Open");
        btn.addActionListener(new ActionListener(){
           public void actionPerformed(ActionEvent e){
              classTwoMap.Get(e.getSource()).setVisible(true);
           }
        });
      
        classTwoMap.Get(btn).setvisible(false);
      }
      
      //Edit:
      public ClassTwo() {
          // This will hide the window when closed, and the button will re-"open" it.
          setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
      }
      

      您可以在按钮处理程序中使用其他答案的任意组合,例如切换功能或其他复杂的想法,例如单例。但主要的是,您应该注意在按钮处理程序中创建一个新窗口,但要在它只被调用一次的地方创建它。

      针对多个窗口和按钮进行了编辑。

      【讨论】:

      • @Kdansky:这个解决方案对我没有用,因为我想同时打开多个 ClassTwo 窗口。所以我每次点击按钮时都必须创建新实例。
      • 您写道“如果打开了一个 ClassTwo 窗口,我如何停止打开 ClassTwo 窗口?”。请澄清。
      • @Kdansky:我的问题已经解决,但下一个问题是它正在打开以前关闭的窗口。见我的Edit
      • @Harry:看我的编辑。更改 classtwo 的构造函数,使窗口永远不会被破坏,而只会被隐藏。
      • @Kdansky:+1,如果在我的情况下只有一个按钮螺母,则您的解决方案可以解决问题,并且按钮数量是动态的。因此,如果我这样做,那么我还必须维护隐藏的打开窗口的列表或地图。那么你知道我该怎么做吗?
      猜你喜欢
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多