Переглянути джерело

new component ProgressIndicator and ajax version of chat that uses it

svn changeset:198/svn branch:toolkit
tags/6.7.0.beta1
Matti Tahvonen 17 роки тому
джерело
коміт
1f8bea7f7f

+ 17
- 0
WebContent/WEB-INF/web.xml Переглянути файл

@@ -91,6 +91,23 @@
<servlet-name>chat</servlet-name>
<url-pattern>/chat/*</url-pattern>
</servlet-mapping>
<!-- APPLICATION: ...demo.ajaxchat -->
<servlet>
<servlet-name>ajaxchat</servlet-name>
<servlet-class>com.itmill.toolkit.terminal.web.ApplicationServlet</servlet-class>
<init-param>
<param-name>application</param-name>
<param-value>com.itmill.toolkit.demo.AjaxChat</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ajaxchat</servlet-name>
<url-pattern>/ajaxchat/*</url-pattern>
</servlet-mapping>

<!-- APPLICATION: ...demo.Login -->
<servlet>

+ 179
- 0
src/com/itmill/toolkit/demo/AjaxChat.java Переглянути файл

@@ -0,0 +1,179 @@
package com.itmill.toolkit.demo;

import java.io.*;
import java.util.*;
import java.lang.ref.WeakReference;

import com.itmill.toolkit.ui.*;
import com.itmill.toolkit.data.*;
import com.itmill.toolkit.demo.features.PropertyPanel;

/** Chat example application.
*
* <p>This example application implements Internet chatroom with the
* following features:
* <ul>
* </ul>
* </p>
*
* @see com.itmill.toolkit.Application
* @see com.itmill.toolkit.ui.FrameWindow
* @see com.itmill.toolkit.terminal.StreamResource
*/

public class AjaxChat
extends com.itmill.toolkit.Application
implements Button.ClickListener {

/** Login name / Alias for chat */
private TextField loginName = new TextField("Your name?", "");

/** Login button */
private Button loginButton = new Button("Enter chat");

/** Text to be said to discussion */
private TextField sayText = new TextField();

/** Button for sending the sayTest to discussion */
private Button say = new Button("Say");

private static Tree userlist = new Tree("Users");
private static Panel messagePane;
private ProgressIndicator connectionstatus;
private static int msgCount = 1;
private static final int MSG_PER_PAGE = 10;
private Window main = new Window("Ajax chat example",
new OrderedLayout(OrderedLayout.ORIENTATION_VERTICAL));

private Item userObject;

private Button leaveButton;
/** Initialize the chat application */
public void init() {
setMainWindow(main);
if(messagePane == null) {
messagePane = new Panel();
messagePane.setCaption("Messages:");
messagePane.addComponent(new ChatMessage("SERVER", "Chat started"));
}
// Initialize user interface
say.dependsOn(sayText);
say.addListener((Button.ClickListener) this);
Panel controls =
new Panel(
"",
new OrderedLayout(OrderedLayout.ORIENTATION_HORIZONTAL));
controls.addComponent(sayText);
sayText.setColumns(40);
controls.addComponent(say);
controls.addComponent(loginName);
loginName.focus();
controls.addComponent(loginButton);
loginButton.dependsOn(loginName);
loginButton.addListener(this);
leaveButton = new Button("Leave", this, "leave");
controls.addComponent(leaveButton);
say.setVisible(false);
sayText.setVisible(false);
this.connectionstatus = new ProgressIndicator();
this.connectionstatus.setIndeterminate(true);
this.connectionstatus.setPollingInterval(2000); // check for new messages every 2 seconds
main.addComponent(this.connectionstatus);
main.addComponent(controls);
main.addComponent(messagePane);
main.addComponent(userlist);

}

/** Handle button actions for login, user listing and saying */
public void buttonClick(Button.ClickEvent event) {

// Say something in discussion
if (event.getSource() == say && sayText.toString().length() > 0) {

// Say something to chatstream
say(sayText.toString());

// Clear the saytext field
sayText.setValue("");
sayText.focus();
}

// Login to application
else if (
event.getSource() == loginButton
&& loginName.toString().length() > 0) {

// Set user name
setUser(loginName.toString());
//TODO remove elements older than ten posts
userlist.addItem(loginName.toString());

// Hide logins controls
loginName.setVisible(false);
loginButton.setVisible(false);

// Show say controls
say.setVisible(true);
sayText.setVisible(true);
sayText.focus();
say("[Joining chat]");

}
}


/** Add message to messages table */
private void say(String text) {
if(text != "") {
synchronized(messagePane) {
msgCount++;
messagePane.addComponent(new ChatMessage(this.loginName.toString(), text));
if(msgCount > MSG_PER_PAGE) {
Label firstMessage = (Label) messagePane.getComponentIterator().next();
messagePane.removeComponent(firstMessage);
}
}
}
}


/** Leave the chat */
public void leave() {
say("[Leaving chat]");
userlist.removeItem(loginName.toString());
this.loginName.setVisible(true);
this.loginButton.setVisible(true);
this.sayText.setVisible(false);
this.say.setVisible(false);
this.leaveButton.setVisible(false);
}

/** Make sure that everybody leaves the chat */
public void finalize() {
leave();
}

private class ChatMessage extends Label {
ChatMessage(String s, String m) {
super( "<small style=\"font-size:x-small;\">"+(new Date()).toString()+
"</small><div><strong style=\"font-weight:bold; \">"+
s+": </strong>" +
m +"</div>");
this.setContentMode(Label.CONTENT_XHTML);
}
}
}

+ 210
- 0
src/com/itmill/toolkit/ui/ProgressIndicator.java Переглянути файл

@@ -0,0 +1,210 @@
/* *************************************************************************
IT Mill Toolkit

Development of Browser User Intarfaces Made Easy

Copyright (C) 2000-2006 IT Mill Ltd
*************************************************************************

This product is distributed under commercial license that can be found
from the product package on license/license.txt. Use of this product might
require purchasing a commercial license from IT Mill Ltd. For guidelines
on usage, see license/licensing-guidelines.html

*************************************************************************
For more information, contact:
IT Mill Ltd phone: +358 2 4802 7180
Ruukinkatu 2-4 fax: +358 2 4802 7181
20540, Turku email: info@itmill.com
Finland company www: www.itmill.com
Primary source for information and releases: www.itmill.com

********************************************************************** */

package com.itmill.toolkit.ui;

import com.itmill.toolkit.data.Property;
import com.itmill.toolkit.data.util.ObjectProperty;
import com.itmill.toolkit.terminal.PaintException;
import com.itmill.toolkit.terminal.PaintTarget;

/**
* ProgressIndicator is component that shows user state of a prosess
* (like long computing or file upload)
*
* ProgressIndicator has two mainmodes. One for indeterminete prosesses and
* other (default) for prosesses which progress can be measured
*
* May view an other property that indicates progress 0...1
*
* @author IT Mill Ltd.
* @version @VERSION@
* @since 29122006
*/
public class ProgressIndicator
extends AbstractField
implements
Property,
Property.Viewer,
Property.ValueChangeListener {

/** Content mode, where the label contains only plain text. The getValue()
* result is coded to XML when painting.
*/
public static final int CONTENT_TEXT = 0;

/** Content mode, where the label contains preformatted text.
*/
public static final int CONTENT_PREFORMATTED = 1;
private boolean indeterminate;

private Property dataSource;

private int pollingInterval;

/** Creates an a new ProgressIndicator. */
public ProgressIndicator() {
setPropertyDataSource(new ObjectProperty(0, Float.class));
}

/** Creates a new instance of ProgressIndicator with given state. */
public ProgressIndicator(Float value) {
setPropertyDataSource(new ObjectProperty(value, Float.class));
}

/** Creates a new instance of ProgressIndicator with stae read from given datasource. */
public ProgressIndicator(Property contentSource) {
setPropertyDataSource(contentSource);
}

/** Get component UIDL tag.
* @return Component UIDL tag as string.
*/
public String getTag() {
return "progressindicator";
}

/** Set the component to read-only.
* Readonly is not used in ProgressIndicator.
* @param readOnly True to enable read-only mode, False to disable it
*/
public void setReadOnly(boolean readOnly) {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
dataSource.setReadOnly(readOnly);
}

/** Is the component read-only ?
* Readonly is not used in ProgressIndicator - this returns allways false.
* @return True iff the component is in read only mode
*/
public boolean isReadOnly() {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
return dataSource.isReadOnly();
}

/** Paint the content of this component.
* @param event PaintEvent.
*/
public void paintContent(PaintTarget target) throws PaintException {
target.addAttribute("indeterminate", indeterminate);
target.addAttribute("pollinginterval", pollingInterval);
target.addAttribute("state", this.getValue().toString());
}

/** Get the value of the ProgressIndicator.
* Value of the ProgressIndicator is Float between 0 and 1
* @return Value of the ProgressIndicator
*/
public Object getValue() {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
return dataSource.getValue();
}

/** Set the value of the ProgressIndicator.
* Value of the ProgressIndicator is the Float between 0 and 1
* @param newValue New value of the ProgressIndicator
*/
public void setValue(Object newValue) {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
this.dataSource.setValue(newValue);
}

public String toString() {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
return dataSource.toString();
}

public Class getType() {
if (dataSource == null)
throw new IllegalStateException("Datasource must be se");
return dataSource.getType();
}

/** Get viewing data-source property. */
public Property getPropertyDataSource() {
return dataSource;
}

/** Set the property as data-source for viewing. */
public void setPropertyDataSource(Property newDataSource) {
// Stop listening the old data source changes
if (dataSource != null
&& Property.ValueChangeNotifier.class.isAssignableFrom(
dataSource.getClass()))
((Property.ValueChangeNotifier) dataSource).removeListener(this);

// Set the new data source
dataSource = newDataSource;

// Listen the new data source if possible
if (dataSource != null
&& Property.ValueChangeNotifier.class.isAssignableFrom(
dataSource.getClass()))
((Property.ValueChangeNotifier) dataSource).addListener(this);
}

/** Get the mode of ProgressIndicator.
*
* @return true if in indeterminate mode
*/
public boolean getContentMode() {
return indeterminate;
}
/**
* Set ProgressIndicator to indeterminate mode
*
* @param newValue true to set to indeterminate mode
*/
public void setIndeterminate(boolean newValue) {
indeterminate = newValue;
}
/**
* Set interval that compnent checks for progress
* @param newValue interval in milliseconds
*/
public void setPollingInterval(int newValue) {
pollingInterval = newValue;
}
/**
* Get interval that component checks for progress
* @return interval in milliseconds
*/
public int getPollingInterval() {
return pollingInterval;
}

}

Завантаження…
Відмінити
Зберегти