Change account wizards to register protocol in separate thread and no more block the UI and shows status text.

cusax-fix
Damian Minkov 15 years ago
parent a8b8cc418a
commit 2a2cfac048

@ -715,7 +715,7 @@ plugin.jabberaccregwizz.RELAY_SUPPORT=Support relay
plugin.jabberaccregwizz.ADD_JINGLE_NODE=Add Jingle Node
plugin.jabberaccregwizz.JID_ADDRESS=JID Address
plugin.jabberaccregwizz.ADDITIONAL_JINGLE_NODES=Additional Jingle Nodes
plugin.jabberaccregwizz.USE_UPNP=Use UPnP
plugin.jabberaccregwizz.USE_UPNP=Use UPnP (Experimental)
# mailbox
plugin.mailbox.OUTGOING=Outgoing Message:

@ -107,6 +107,16 @@ public class Wizard
private final java.util.List<WizardListener> wizardListeners
= new Vector<WizardListener>();
/**
* Status label, show when connecting.
*/
private JLabel statusLabel = new JLabel();
/**
* If account is signing-in ignore close.
*/
private boolean isCurrentlySigningIn = false;
/**
* This method accepts a java.awt.Dialog object as the javax.swing.JDialog's
* parent.
@ -327,7 +337,8 @@ public boolean isBackButtonEnabled()
*/
public void setBackButtonEnabled(boolean newValue)
{
wizardModel.setBackButtonEnabled(newValue);
if(!(isCurrentlySigningIn && newValue))
wizardModel.setBackButtonEnabled(newValue);
}
/**
@ -460,6 +471,12 @@ private void initComponents()
buttonPanel.add(buttonBox, java.awt.BorderLayout.EAST);
JPanel statusPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER));
statusPanel.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));
statusPanel.add(statusLabel);
buttonPanel.add(statusPanel, java.awt.BorderLayout.CENTER);
java.awt.Container contentPane = getContentPane();
contentPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
contentPane.add(cardPanel, java.awt.BorderLayout.CENTER);
@ -531,6 +548,9 @@ private void fireWizardEvent(int eventCode)
*/
protected void close(boolean isEscaped)
{
if(isCurrentlySigningIn)
return;
this.close(Wizard.CANCEL_RETURN_CODE);
}
@ -664,4 +684,39 @@ public void setFinishButtonText(String text)
{
this.setFinishButtonDefaultText(text);
}
/**
* Changes cursor and status label, informing user we are in process
* of connecting.
*/
void startCommittingPage()
{
isCurrentlySigningIn = true;
setBackButtonEnabled(false);
setCancelButtonEnabled(false);
setNextFinishButtonEnabled(false);
statusLabel.setText(GuiActivator.getResources().getI18NString(
"service.gui.CONNECTING"));
setCursor(new Cursor(Cursor.WAIT_CURSOR));
}
/**
* Changes cursor and status label, informing user we finished the process
* of connecting.
*/
void stopCommittingPage()
{
isCurrentlySigningIn = false;
statusLabel.setText("");
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
setBackButtonEnabled(true);
setCancelButtonEnabled(true);
setNextFinishButtonEnabled(true);
}
}

@ -13,6 +13,8 @@
import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.service.gui.*;
import javax.swing.*;
/**
* This class is responsible for reacting to events generated by pushing any
* of the three buttons, 'Next', 'Previous', and 'Cancel.' Based on what
@ -69,38 +71,11 @@ private void cancelButtonPressed() {
* ID that the current panel identifies as the next panel, and displays
* the panel that it's identifying.
*/
private void nextButtonPressed() {
WizardModel model = wizard.getModel();
WizardPage page = model.getCurrentWizardPage();
try
{
page.commitPage();
}
catch (Exception ex)
{
//lots of things may fail on page next, like for example parameter
//validation or account initialization. If this is what happened here
//just show an error and leave everything on the same page so that
//the user would have the chance to correct errors.
new ErrorDialog(
null,
GuiActivator.getResources().getI18NString("service.gui.ERROR"),
ex.getMessage(),
ex).showDialog();
return;
}
Object nextPageIdentifier = page.getNextPageIdentifier();
private void nextButtonPressed()
{
wizard.startCommittingPage();
if (nextPageIdentifier
.equals(WizardPage.FINISH_PAGE_IDENTIFIER)) {
wizard.close(Wizard.FINISH_RETURN_CODE);
}
else {
wizard.setCurrentPage(nextPageIdentifier);
}
new Thread(new PageCommitThread()).start();
}
/**
@ -150,4 +125,58 @@ void resetButtonsToPanelRules()
model.setNextFinishButtonText(wizard.getNextButtonDefaultText());
}
}
/**
* Runs committing page in new thread to avoid blocking UI thread.
*/
private class PageCommitThread
implements Runnable
{
/**
* Commits wizard page.
*/
public void run()
{
WizardModel model = wizard.getModel();
final WizardPage page = model.getCurrentWizardPage();
try
{
page.commitPage();
}
catch (Exception ex)
{
//lots of things may fail on page next, like for example parameter
//validation or account initialization. If this is what happened here
//just show an error and leave everything on the same page so that
//the user would have the chance to correct errors.
new ErrorDialog(
null,
GuiActivator.getResources().getI18NString("service.gui.ERROR"),
ex.getMessage(),
ex).showDialog();
return;
}
wizard.stopCommittingPage();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
Object nextPageIdentifier = page.getNextPageIdentifier();
if (nextPageIdentifier
.equals(WizardPage.FINISH_PAGE_IDENTIFIER))
{
wizard.close(Wizard.FINISH_RETURN_CODE);
}
else
{
wizard.setCurrentPage(nextPageIdentifier);
}
}
});
}
}
}

@ -73,6 +73,16 @@ public class NewAccountDialog
private JEditorPane errorMessagePane;
/**
* If account is signing-in ignore close.
*/
private boolean isCurrentlySigningIn = false;
/**
* Status label, show when connecting.
*/
private JLabel statusLabel = new JLabel();
/**
* Creates the dialog and initializes the UI.
*/
@ -91,9 +101,14 @@ public NewAccountDialog()
this.networkPanel.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel statusPanel = new TransparentPanel(
new FlowLayout(FlowLayout.CENTER));
statusPanel.add(statusLabel);
this.mainPanel.add(buttonPanel, BorderLayout.SOUTH);
this.buttonPanel.add(advancedButton, BorderLayout.WEST);
this.buttonPanel.add(rightButtonPanel, BorderLayout.EAST);
this.buttonPanel.add(statusPanel, BorderLayout.CENTER);
this.advancedButton.addActionListener(this);
this.rightButtonPanel.add(addAccountButton);
@ -325,7 +340,7 @@ private void loadSelectedWizard(AccountRegistrationWizard wizard)
addAccountButton.setEnabled(
!(wizard instanceof EmptyAccountRegistrationWizard));
advancedButton.setEnabled(
!(wizard instanceof EmptyAccountRegistrationWizard));
!(wizard instanceof EmptyAccountRegistrationWizard));
accountPanel.revalidate();
accountPanel.repaint();
@ -397,6 +412,135 @@ public void actionPerformed(ActionEvent event)
this.dispose();
}
else if (sourceButton.equals(addAccountButton))
{
startConnecting(wizardContainer);
new Thread(new ProtocolSignInThread(
wizard, wizardContainer)).start();
}
else if (sourceButton.equals(cancelButton))
{
this.dispose();
}
}
/**
* Shows the new account dialog.
*/
public static void showNewAccountDialog()
{
if (newAccountDialog == null)
newAccountDialog = new NewAccountDialog();
newAccountDialog.pack();
newAccountDialog.setVisible(true);
}
/**
* Remove the newAccountDialog, when the window is closed.
* @param isEscaped indicates if the dialog has been escaped
*/
protected void close(boolean isEscaped)
{
if(isCurrentlySigningIn)
return;
dispose();
}
/**
* Remove the newAccountDialog on dispose.
*/
public void dispose()
{
if(isCurrentlySigningIn)
return;
newAccountDialog = null;
super.dispose();
}
/**
* Overrides set visible to disable closing dialog if currently signing-in.
*
* @param visible
*/
@Override
public void setVisible(boolean visible)
{
if(isCurrentlySigningIn)
return;
super.setVisible(visible);
}
private void startConnecting(AccountRegWizardContainerImpl wizardContainer)
{
isCurrentlySigningIn = true;
advancedButton.setEnabled(false);
addAccountButton.setEnabled(false);
cancelButton.setEnabled(false);
statusLabel.setText(GuiActivator.getResources().getI18NString(
"service.gui.CONNECTING"));
setCursor(new Cursor(Cursor.WAIT_CURSOR));
}
private void stopConnecting(AccountRegWizardContainerImpl wizardContainer)
{
isCurrentlySigningIn = false;
statusLabel.setText("");
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
advancedButton.setEnabled(true);
addAccountButton.setEnabled(true);
cancelButton.setEnabled(true);
}
/**
* Makes protocol operations in different thread.
*/
private class ProtocolSignInThread
implements Runnable
{
/**
* The wizard to use.
*/
AccountRegistrationWizard wizard;
/**
* The container of the wizard.
*/
AccountRegWizardContainerImpl wizardContainer;
/**
* Creates <tt>ProtocolSignInThread</tt>.
* @param wizard the wizard to use.
* @param wizardContainer the container of the wizard.
*/
ProtocolSignInThread(AccountRegistrationWizard wizard,
AccountRegWizardContainerImpl wizardContainer)
{
this.wizard = wizard;
this.wizardContainer = wizardContainer;
}
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p/>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see Thread#run()
*/
public void run()
{
ProtocolProviderService protocolProvider;
try
@ -404,7 +548,7 @@ else if (sourceButton.equals(addAccountButton))
if(wizard == emptyWizard)
{
loadErrorMessage(GuiActivator.getResources().getI18NString(
"service.gui.CHOOSE_NETWORK"));
"service.gui.CHOOSE_NETWORK"));
}
protocolProvider = wizard.signin();
@ -413,11 +557,28 @@ else if (sourceButton.equals(addAccountButton))
{
wizardContainer.saveAccountWizard(protocolProvider, wizard);
this.dispose();
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
stopConnecting(wizardContainer);
NewAccountDialog.this.dispose();
}
});
}
}
catch (OperationFailedException e)
{
// make sure buttons don't stay disabled
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
stopConnecting(wizardContainer);
}
});
// If the sign in operation has failed we don't want to close
// the dialog in order to give the user the possibility to
// retry.
@ -428,23 +589,32 @@ else if (sourceButton.equals(addAccountButton))
== OperationFailedException.ILLEGAL_ARGUMENT)
{
loadErrorMessage(GuiActivator.getResources().getI18NString(
"service.gui.USERNAME_NULL"));
"service.gui.USERNAME_NULL"));
}
else if (e.getErrorCode()
== OperationFailedException.IDENTIFICATION_CONFLICT)
{
loadErrorMessage(GuiActivator.getResources().getI18NString(
"service.gui.USER_EXISTS_ERROR"));
"service.gui.USER_EXISTS_ERROR"));
}
else
{
loadErrorMessage(GuiActivator.getResources().getI18NString(
"service.gui.ACCOUNT_CREATION_FAILED",
new String[]{e.getMessage()}));
"service.gui.ACCOUNT_CREATION_FAILED",
new String[]{e.getMessage()}));
}
}
catch (Exception e)
{
// make sure buttons don't stay disabled
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
stopConnecting(wizardContainer);
}
});
// If the sign in operation has failed we don't want to close
// the dialog in order to give the user the possibility to
// retry.
@ -452,44 +622,9 @@ else if (e.getErrorCode()
logger.debug("The sign in operation has failed.");
loadErrorMessage(GuiActivator.getResources().getI18NString(
"service.gui.ACCOUNT_CREATION_FAILED",
new String[]{e.getMessage()}));
"service.gui.ACCOUNT_CREATION_FAILED",
new String[]{e.getMessage()}));
}
}
else if (sourceButton.equals(cancelButton))
{
this.dispose();
}
}
/**
* Shows the new account dialog.
*/
public static void showNewAccountDialog()
{
if (newAccountDialog == null)
newAccountDialog = new NewAccountDialog();
newAccountDialog.pack();
newAccountDialog.setVisible(true);
}
/**
* Remove the newAccountDialog, when the window is closed.
* @param isEscaped indicates if the dialog has been escaped
*/
protected void close(boolean isEscaped)
{
dispose();
}
/**
* Remove the newAccountDialog on dispose.
*/
public void dispose()
{
newAccountDialog = null;
super.dispose();
}
}

Loading…
Cancel
Save