как остановить открытие повторяющегося окна с помощью Smack API в разгаре?

У меня есть 2 класса свинга, которые расширяют JFrame. Оба имеют метод show() в конструкторе. Из ClassOne я позвонил ClassTwo как new ClassTwo() по событию нажатия кнопки. Но если я снова нажму кнопку, откроется новое окно для ClassTwo. Итак, как я могу остановить открытие окна ClassTwo, если открыто одно окно ClassTwo?

Изменить

теперь эта проблема решена, но теперь, когда я впервые открываю окно ClassTwo, оно показывает одно окно. Затем, после его закрытия, когда я снова открываю окно ClassTwo, открывается два окна, и этот счет продолжает увеличиваться. Почему это происходит?

ИЗМЕНИТЬ 2

Я обнаружил, что это не проблема свинга, а проблема с классом MultiUsreChat Samck API. Так что помогите мне те, кто работал над этим.

код в 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

конструктор classone

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);
       }
     }
  });
}

person Harry Joy    schedule 02.02.2011    source источник


Ответы (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);
}

Вы можете использовать любую комбинацию других ответов внутри обработчика кнопки, например функцию переключения или другие сложные идеи, такие как синглтон. Но главное, вы должны отметить создание нового окна в обработчике кнопки, но создать его где-нибудь, где оно вызывается ровно один раз.

Отредактировано для нескольких окон и кнопок.

person Kajetan Abt    schedule 14.02.2011
comment
@Kdansky: это решение бесполезно для меня, потому что я хочу, чтобы несколько окон ClassTwo открывались одновременно. Поэтому мне приходится создавать новый экземпляр каждый раз, когда я нажимаю кнопку. - person Harry Joy; 14.02.2011
comment
Вы написали Итак, как я могу остановить открытие окна ClassTwo, если открыто одно окно ClassTwo?. Просьба уточнить. - person Kajetan Abt; 14.02.2011
comment
@Kdansky: Это был мой вопрос, который был решен, но следующий вопрос заключается в том, что он открывает ранее закрытые окна. см. мой Edit. - person Harry Joy; 14.02.2011
comment
@Harry: смотри мое редактирование. Измените конструктор classtwo, чтобы окно никогда не уничтожалось, а только скрывалось. - person Kajetan Abt; 14.02.2011
comment
@Kdansky: +1, ваше решение решает проблему, если есть только одна гайка кнопки, в моем случае есть динамическое количество кнопок. Поэтому, если мне это нравится, мне также нужно поддерживать список или карту открытых окон, которые скрыты. Итак, у вас есть какие-либо идеи о том, как я могу это сделать? - person Harry Joy; 14.02.2011
comment
Я бы рекомендовал использовать HashMap‹JButton, ClassTwo› вместо одной переменной. Таким образом, вы всегда легко знаете, какое окно принадлежит какой кнопке. - person Kajetan Abt; 14.02.2011
comment
@Kdansky: спасибо за помощь и время. - person Harry Joy; 14.02.2011
comment
В следующий раз вы должны просто вставить больше кода, так как все остальные ответы были идентичны моему. ;) - person Kajetan Abt; 14.02.2011

Не делайте кадр видимым в конструкторе ClassTwo. Вместо этого сохраните ссылку на classTwo в classOne и при нажатии кнопки сделайте ее видимой, например:

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

Также измените операцию закрытия classTwo по умолчанию, чтобы скрыть при закрытии вместо выхода:

setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

Таким образом, не имеет значения, сколько раз была нажата кнопка, потому что все, что она делает, это делает существующий экземпляр видимым. Он не создает новые экземпляры.

person dogbane    schedule 02.02.2011
comment
эта проблема решена, но теперь, когда я впервые открываю окно ClassTwo, оно показывает одно окно. Затем, после его закрытия, когда я снова открываю окно ClassTwo, открывается два окна, и этот счет продолжает увеличиваться. Почему это происходит? - person Harry Joy; 02.02.2011
comment
Ваш Edit # 2 не объясняет, как вы открываете окно. Я полагаю, что вы все еще где-то создаете новые экземпляры окна ClassTwo. Создайте только один экземпляр в конструкторе ClassOne, а затем установите его видимость на кнопке. +1 к проклятию. - person Kajetan Abt; 09.02.2011
comment
@Kdansky: я добавил полную часть кода, в которой я вызываю ClassTwo. и ClassTwo, который открывает ранее закрытые окна. Но если вы хотите, я могу поделиться своим полным кодом. ??? - person Harry Joy; 11.02.2011
comment
В исходном коде отсутствуют: обработчик кнопки и конструктор ClassOne. Какие две части представляют интерес. - person Kajetan Abt; 11.02.2011
comment
@Kdansky: я обновил свой вопрос, указав исходный код конструктора classone. Посмотри. reply me using @Harry so i can get your reply even if i'm not in this question. - person Harry Joy; 12.02.2011

В ClassOne вы могли просто вспомнить, открывали ли вы новый ClassTwo с помощью boolean.

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

Вы также должны подключиться к событию dispose второго класса, чтобы сбросить флаг classTwoShown.

person Qwerky    schedule 02.02.2011

попробуйте использовать шаблон singleton

person yahh    schedule 10.02.2011
comment
не могли бы вы объяснить больше, потому что я не знаю об однотонном шаблоне. - person Harry Joy; 10.02.2011