Странная проблема с java CardLayout в JFrame

привет, у меня есть Jframe с CardLayout и 3 карты. У меня есть ActionListener на кнопке на первой карточке.

Этот код работает хорошо:

JButton btnLogin = new JButton("Login");
btnLogin.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, "wait");
    }
}

проблема в том, что когда я добавляю код для входа на сервер (я разрабатываю клиент xmpp):

JButton btnLogin = new JButton("Login");
btnLogin.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, "wait");
        xmppManager = new Xmpp("jabberserver", 5222);
        try {
            xmppManager.init();
        } catch (XMPPException e) {
            e.printStackTrace();
        }
        cl.show(cards, "userList");
    }
}

По сути, мне нужно показать карточку «подождите», когда пользователь нажимает кнопку входа, выполняет вход, а затем показывает другую карточку. Но в этом случае карточка «ожидание» не отображается, она выполняет вход в систему (это занимает около 5 секунд) и показывает непосредственно окончательную карточку «userList».

Что мне не хватает?


person Laphroaig    schedule 17.02.2011    source источник


Ответы (2)


Весь код выполняется в потоке отправки событий, что предотвращает перерисовку графического интерфейса. Вам нужно, чтобы вызов сервера выполнялся в отдельном потоке, чтобы вы не блокировали EDT.

Прочтите раздел руководства Swing по Параллелизм для получения дополнительной информации и предлагаемое решение.

person camickr    schedule 17.02.2011
comment
Привет спасибо! Теперь я закрыл вызов сервера в EventQueue.invokeLater(new Runnable() {public void run() {//вызов сервера}, и он работает. Как вы думаете, это хорошее решение? - person Laphroaig; 17.02.2011
comment
Я не вижу необходимости манипулировать сервером в EDT, если только я неправильно не истолковал ваш пост. Вы должны щелкнуть ссылку в сообщении camickr выше, чтобы узнать об использовании объекта SwingWorker, который поможет вам выполнять фоновые потоки в Swing. - person Hovercraft Full Of Eels; 17.02.2011

Возможно, необходимо вызвать перерисовку экрана после того, как вы покажете, пожалуйста, подождите? Он может не запускаться автоматически.

person corsiKa    schedule 17.02.2011
comment
Привет спасибо. Я только что добавил frame.repaint(); после cl.show(карты, ждать); но он меняется. он застрял на первой карте и после входа в систему он сразу переходит на 3-ю карту... - person Laphroaig; 17.02.2011
comment
только что попробовалcards.repaint() тоже. ничего такого. - person Laphroaig; 17.02.2011
comment
Для CardLayout в этом нет необходимости. Сообщение camickr лучше всего описывает проблему и ее решение. - person Hovercraft Full Of Eels; 17.02.2011