/* * Copyright (c) 2011, grossmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.impl.widgets.composed; import java.util.HashSet; import java.util.Set; import org.jowidgets.api.color.Colors; import org.jowidgets.api.login.ILoginCancelListener; import org.jowidgets.api.login.ILoginInterceptor; import org.jowidgets.api.login.ILoginResult; import org.jowidgets.api.login.ILoginResultCallback; import org.jowidgets.api.threads.IUiThreadAccess; import org.jowidgets.api.toolkit.Toolkit; import org.jowidgets.api.widgets.IButton; import org.jowidgets.api.widgets.IComposite; import org.jowidgets.api.widgets.IFrame; import org.jowidgets.api.widgets.IInputField; import org.jowidgets.api.widgets.ILoginDialog; import org.jowidgets.api.widgets.IProgressBar; import org.jowidgets.api.widgets.IValidationResultLabel; import org.jowidgets.api.widgets.blueprint.ITextLabelBluePrint; import org.jowidgets.api.widgets.blueprint.factory.IBluePrintFactory; import org.jowidgets.api.widgets.descriptor.setup.ILoginDialogSetup; import org.jowidgets.common.types.Markup; import org.jowidgets.common.widgets.controller.IActionListener; import org.jowidgets.common.widgets.controller.IInputListener; import org.jowidgets.common.widgets.layout.MigLayoutDescriptor; import org.jowidgets.i18n.api.IMessage; import org.jowidgets.tools.widgets.wrapper.WindowWrapper; import org.jowidgets.util.Assert; import org.jowidgets.validation.ValidationResult; public class LoginDialogImpl extends WindowWrapper implements ILoginDialog { private static final IMessage USERNAME = Messages.getMessage("LoginDialogImpl.username"); private static final IMessage PASSWORD = Messages.getMessage("LoginDialogImpl.password"); private final IUiThreadAccess uiThreadAccess; private final Set<ILoginCancelListener> cancelListeners; private final IFrame frame; private final ILoginInterceptor loginInterceptor; private final IValidationResultLabel validationResultLabel; private final IInputField<String> usernameField; private final IInputField<String> passwordField; private final IButton loginButton; private final IButton cancelButton; private final IProgressBar progressBar; private ILoginResult result; private boolean disposed; private boolean loginButtonPressed; public LoginDialogImpl(final IFrame frame, final ILoginDialogSetup setup) { super(frame); Assert.paramNotNull(frame, "frame"); Assert.paramNotNull(setup, "setup"); Assert.paramNotNull(setup.getInterceptor(), "setup.getInterceptor()"); this.uiThreadAccess = Toolkit.getUiThreadAccess(); this.cancelListeners = new HashSet<ILoginCancelListener>(); this.frame = frame; this.loginInterceptor = setup.getInterceptor(); final IBluePrintFactory bpf = Toolkit.getBluePrintFactory(); frame.setLayout(new MigLayoutDescriptor("0[grow]0", "0[]0[grow]0[12!]0")); if (setup.getMinSize() != null) { frame.setMinSize(setup.getMinSize()); } //set logo, or if not exists if (setup.getLogo() != null) { frame.add(bpf.icon(setup.getLogo()), "growx, growy, wrap"); } //set login label else { if (setup.getLoginLabel() != null) { final IComposite labelComposite = frame.add(bpf.composite().setBackgroundColor(Colors.WHITE), "grow, wrap"); labelComposite.setLayout(new MigLayoutDescriptor("15[grow]15", "15[grow]15")); final ITextLabelBluePrint labelBp = bpf.textLabel().setFontSize(25).setStrong().setFontName("Arial"); labelBp.setText(setup.getLoginLabel()).setMarkup(Markup.DEFAULT); labelBp.setForegroundColor(Colors.DARK_GREY); labelComposite.add(labelBp, "grow"); } else { frame.add(bpf.textLabel(""), "grow, wrap"); } } //create content pane final IComposite content = frame.add(bpf.composite(), "alignx r, wrap"); content.setLayout(new MigLayoutDescriptor("20[grow]8[grow, 200!]20", "20[20!]15[][]45[grow]10")); //validation label validationResultLabel = content.add(bpf.validationResultLabel(), "span2, growx, wrap"); //input fields content.add(bpf.textLabel(USERNAME.get()).alignRight(), "alignx r"); usernameField = content.add(bpf.inputFieldString(), "growx, wrap"); content.add(bpf.textLabel(PASSWORD.get()).alignRight(), "alignx r"); passwordField = content.add(bpf.inputFieldString().setPasswordPresentation(true), "growx, wrap"); //button bar final IComposite buttonBar = content.add(bpf.composite(), "span2, alignx r, growy"); buttonBar.setLayout(new MigLayoutDescriptor("0[][]0", "0[]0")); this.loginButton = buttonBar.add(setup.getLoginButton(), "w 80::, aligny b, sg bg"); this.cancelButton = buttonBar.add(setup.getCancelButton(), "w 80::, aligny b, sg bg"); loginButton.setBackgroundColor(frame.getBackgroundColor()); cancelButton.setBackgroundColor(frame.getBackgroundColor()); frame.setDefaultButton(loginButton); //progress bar this.progressBar = frame.add(bpf.progressBar().setIndeterminate(true), "growx, growy, aligny b"); progressBar.setVisible(false); //register listeners usernameField.addInputListener(new ValidationInputListener()); passwordField.addInputListener(new ValidationInputListener()); loginButton.addActionListener(new LoginActionListener()); cancelButton.addActionListener(new CancelActionListener()); usernameField.requestFocus(); } @Override public ILoginResult doLogin() { setVisible(true); return result; } @Override public void dispose() { if (!disposed) { this.disposed = true; super.dispose(); } } private void loginButtonPressed() { loginButtonPressed = true; loginButton.setEnabled(false); usernameField.setEnabled(false); passwordField.setEnabled(false); progressBar.setIndeterminate(true); progressBar.setVisible(true); validationResultLabel.setEmpty(); } private void loginGranted() { uiThreadAccess.invokeLater(new Runnable() { @Override public void run() { result = new LoginResult(true); dispose(); } }); } private void loginDenied(final String reason) { uiThreadAccess.invokeLater(new Runnable() { @Override public void run() { if (!disposed) { validationResultLabel.setResult(ValidationResult.error(reason)); loginButtonPressed = false; loginButton.setEnabled(true); usernameField.setEnabled(true); passwordField.setEnabled(true); progressBar.setVisible(false); frame.layoutBegin(); frame.layoutEnd(); frame.setDefaultButton(loginButton); } } }); } private final class LoginActionListener implements IActionListener { @Override public void actionPerformed() { if (!loginButtonPressed) { loginButtonPressed(); final String username = usernameField.getValue(); final String password = passwordField.getValue(); final Thread thread = new Thread(new Runnable() { @Override public void run() { loginInterceptor.login(new LoginResultCallback(), username, password, uiThreadAccess); } }); thread.setName("LoginDialogLoginThread"); thread.setDaemon(true); thread.start(); } } } private final class LoginResultCallback implements ILoginResultCallback { @Override public void granted() { loginGranted(); } @Override public void denied(final String reason) { loginDenied(reason); } @Override public void addCancelListener(final ILoginCancelListener cancelListener) { cancelListeners.add(cancelListener); } } private final class CancelActionListener implements IActionListener { @Override public void actionPerformed() { result = new LoginResult(false); for (final ILoginCancelListener listener : cancelListeners) { listener.canceled(); } dispose(); } } private final class ValidationInputListener implements IInputListener { @Override public void inputChanged() { validationResultLabel.setEmpty(); } } private final class LoginResult implements ILoginResult { private final boolean isLoggedOn; private LoginResult(final boolean isLoggedOn) { this.isLoggedOn = isLoggedOn; } @Override public boolean isLoggedOn() { return isLoggedOn; } } }