Java tutorial
/******************************************************************************* * Copyright (c) 2013 Pronoia Health LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Pronoia Health LLC - initial API and implementation *******************************************************************************/ package com.pronoiahealth.olhie.client.widgets.chat; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.enterprise.event.Observes; import javax.inject.Inject; import org.jboss.errai.bus.client.ErraiBus; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.bus.client.api.messaging.MessageBus; import org.jboss.errai.bus.client.api.messaging.MessageCallback; import com.github.gwtbootstrap.client.ui.Button; import com.github.gwtbootstrap.client.ui.TextBox; import com.github.gwtbootstrap.client.ui.constants.ButtonType; import com.github.gwtbootstrap.client.ui.constants.IconType; import com.github.gwtbootstrap.client.ui.resources.ButtonSize; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.MouseUpEvent; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.DialogBox; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.pronoiahealth.olhie.client.shared.constants.OfferActionEnum; import com.pronoiahealth.olhie.client.shared.constants.OfferEnum; import com.pronoiahealth.olhie.client.shared.events.local.WindowResizeEvent; import com.pronoiahealth.olhie.client.shared.events.offers.SendMessageEvent; /** * ChatDialog.java<br/> * Responsibilities:<br/> * 1. When ChatDialog is created a new listener is created on the message bus * tuned to the channelId. No communication can started until the channel has * been accepted by the peer. When the other side disconnects or closes the * dialog the bus listener is removed. At that time this chat is essentially * non-functional. * * @author John DeStefano * @version 1.0 * @since Jul 15, 2013 * */ @Dependent public class ChatDialog extends DialogBox { public enum BoxShade { ME, PEER, SERVER }; @Inject private Event<SendMessageEvent> sendMessageEvent; private String dialogChannelId; private ChatDialogCloseHandler dialogCloseHandler; private String caption; private TextBox txtBox; private HTMLPanel chatTxtPanel; private MessageBus bus = ErraiBus.get(); private boolean connectionAccepted; @Inject public ChatDialog() { super(); // Dialog properties setAutoHideEnabled(false); setModal(false); setAnimationEnabled(true); // Style getElement().setAttribute("style", "z-index: 30000; opacity: .70;"); // Set up the dialog box contents VerticalPanel vp = new VerticalPanel(); vp.setHeight("450px"); vp.setWidth("250px"); vp.setSpacing(10); // Build Chat widget chatTxtPanel = new HTMLPanel((String) null); vp.add(chatTxtPanel); chatTxtPanel.setStyleName("ph-ChatDialog-Txt", true); // Build entry and exit button HorizontalPanel hp = new HorizontalPanel(); vp.add(hp); txtBox = new TextBox(); hp.add(txtBox); txtBox.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { String msg = txtBox.getText(); addMePanel(msg); txtBox.setText(""); txtBox.setFocus(true); sendMessageEvent.fire(new SendMessageEvent(dialogChannelId, msg, caption)); } } }); txtBox.setStyleName("ph-ChatDialog-TxtBox", true); txtBox.setWidth("175px"); txtBox.setEnabled(false); // Button Button endBtn = new Button("End"); endBtn.setIcon(IconType.SIGNOUT); endBtn.setSize(ButtonSize.SMALL); endBtn.setType(ButtonType.PRIMARY); endBtn.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { dialogCloseHandler.closeDialog(dialogChannelId, caption); } }); hp.add(endBtn); // Set widget setWidget(vp); } /** * Called by ChatDialogFactory * * @param caption * @param channelId * @param closeHandler */ public void initDialog(String caption, String channelId, ChatDialogCloseHandler closeHandler) { this.dialogChannelId = channelId; this.dialogCloseHandler = closeHandler; this.caption = caption; String html = "<div class='ph-ChatDialog-Caption'>" + caption + "</div>"; getCaption().setHTML(html); // Create a listener bus.subscribe(this.dialogChannelId, new MessageCallback() { @Override public void callback(Message message) { OfferActionEnum action = message.get(OfferActionEnum.class, OfferEnum.OFFER_ACTION); String msg = message.get(String.class, OfferEnum.MSG); switch (action) { case CREATED: // Doesn't handle break; case ACCEPTED: handleAccept(); break; case OFFER: // Doesn't handle break; case PEER_DISCONNECTED: handleDisconnect(msg); break; case REJECTED: handleReject(msg); break; case NEW_MSG: handleNewMsg(msg); break; default: break; } } }); } /** * The window can be dragged off the screen or the window can be resized * hidding the dialog. This method in conjunction with the monitoring window * rezie events prevents that from happening. * * @see com.google.gwt.user.client.ui.DialogBox#endDragging(com.google.gwt.event.dom.client.MouseUpEvent) */ @Override protected void endDragging(MouseUpEvent event) { int genericMargin = 60; int leftMargin = -(this.getOffsetWidth() - genericMargin); int lowerMargin = Window.getClientHeight() - genericMargin; int rightMargin = Window.getClientWidth() - genericMargin; int upperMargin = 0; if (this.getAbsoluteLeft() > rightMargin) { this.setPopupPosition(rightMargin, this.getPopupTop()); } if (this.getAbsoluteLeft() < leftMargin) { this.setPopupPosition(leftMargin, this.getPopupTop()); } if (this.getAbsoluteTop() > lowerMargin) { this.setPopupPosition(this.getPopupLeft(), lowerMargin); } if (this.getAbsoluteTop() < upperMargin) { this.setPopupPosition(this.getPopupLeft(), upperMargin); } super.endDragging(event); } /** * @param windowResizeEvent */ protected void observesWindowResizeEvent(@Observes WindowResizeEvent windowResizeEvent) { endDragging(null); } /** * This can be called from a return message */ public void handleAccept() { if (isConnectionAccepted() == false) { connectionAccepted = true; txtBox.setEnabled(true); addPeerPanel("Request has been accepted."); } } public void handleDisconnect(String msg) { destroyListener(); txtBox.setEnabled(false); addServerPanel(msg); } private void handleReject(String msg) { destroyListener(); addPeerPanel("Can't chat right now."); txtBox.setEnabled(false); addServerPanel(msg); } private void handleNewMsg(String msg) { if (isConnectionAccepted() == true) { addPeerPanel(msg); } } private void addMePanel(String txt) { HTMLPanel panel = this.createPanel(txt, BoxShade.ME); chatTxtPanel.add(panel); } private void addPeerPanel(String txt) { HTMLPanel panel = this.createPanel(txt, BoxShade.PEER); chatTxtPanel.add(panel); } private void addServerPanel(String txt) { HTMLPanel panel = this.createPanel(txt, BoxShade.SERVER); chatTxtPanel.add(panel); } private HTMLPanel createPanel(String txt, BoxShade shade) { HTMLPanel panel = new HTMLPanel(txt); if (shade == BoxShade.ME) { panel.setStyleName("ph-ChatDialog-BoxShade-Me", true); } else if (shade == BoxShade.PEER) { panel.setStyleName("ph-ChatDialog-BoxShade-Peer", true); } else { panel.setStyleName("ph-ChatDialog-BoxShade-Server", true); } return panel; } public void destroyListener() { if (isConnectionAccepted() == true) { bus.unsubscribeAll(this.dialogChannelId); } connectionAccepted = false; } public boolean isConnectionAccepted() { return this.connectionAccepted; } }