Added Timeout on Chat Rooms.

git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@4871 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Derek DeMoro
2006-08-10 04:43:04 +00:00
committed by derek
parent 0dba8372ee
commit f14902dc4b
11 changed files with 1187 additions and 1214 deletions

View File

@ -1,202 +1,203 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4" relativePaths="true"> <project version="4" relativePaths="true">
<component name="AntConfiguration"> <component name="AntConfiguration">
<defaultAnt bundledAnt="true" /> <defaultAnt bundledAnt="true" />
</component> </component>
<component name="CodeStyleSettingsManager"> <component name="CodeStyleSettingsManager">
<option name="PER_PROJECT_SETTINGS" /> <option name="PER_PROJECT_SETTINGS" />
<option name="USE_PER_PROJECT_SETTINGS" value="false" /> <option name="USE_PER_PROJECT_SETTINGS" value="false" />
</component> </component>
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" /> <option name="DEFAULT_COMPILER" value="Javac" />
<option name="CLEAR_OUTPUT_DIRECTORY" value="true" /> <option name="CLEAR_OUTPUT_DIRECTORY" value="true" />
<option name="DEPLOY_AFTER_MAKE" value="0" /> <option name="DEPLOY_AFTER_MAKE" value="0" />
<resourceExtensions> <resourceExtensions>
<entry name=".+\.(properties|xml|html|dtd|tld)" /> <entry name=".+\.(properties|xml|html|dtd|tld)" />
<entry name=".+\.(gif|png|jpeg|jpg)" /> <entry name=".+\.(gif|png|jpeg|jpg)" />
</resourceExtensions> </resourceExtensions>
<wildcardResourcePatterns> <wildcardResourcePatterns>
<entry name="?*.properties" /> <entry name="?*.properties" />
<entry name="?*.xml" /> <entry name="?*.xml" />
<entry name="?*.html" /> <entry name="?*.html" />
<entry name="?*.dtd" /> <entry name="?*.dtd" />
<entry name="?*.tld" /> <entry name="?*.tld" />
<entry name="?*.gif" /> <entry name="?*.gif" />
<entry name="?*.png" /> <entry name="?*.png" />
<entry name="?*.jpeg" /> <entry name="?*.jpeg" />
<entry name="?*.jpg" /> <entry name="?*.jpg" />
</wildcardResourcePatterns> </wildcardResourcePatterns>
</component> </component>
<component name="DataSourceManager" /> <component name="DataSourceManager" />
<component name="DataSourceManagerImpl" /> <component name="DataSourceManagerImpl" />
<component name="DependenciesAnalyzeManager"> <component name="DependenciesAnalyzeManager">
<option name="myForwardDirection" value="false" /> <option name="myForwardDirection" value="false" />
</component> </component>
<component name="DependencyValidationManager" /> <component name="DependencyValidationManager" />
<component name="EntryPointsManager"> <component name="EntryPointsManager">
<entry_points /> <entry_points />
</component> </component>
<component name="ExportToHTMLSettings"> <component name="ExportToHTMLSettings">
<option name="PRINT_LINE_NUMBERS" value="false" /> <option name="PRINT_LINE_NUMBERS" value="false" />
<option name="OPEN_IN_BROWSER" value="false" /> <option name="OPEN_IN_BROWSER" value="false" />
<option name="OUTPUT_DIRECTORY" /> <option name="OUTPUT_DIRECTORY" />
</component> </component>
<component name="GUI Designer component loader factory" /> <component name="GUI Designer component loader factory" />
<component name="JavacSettings"> <component name="JavacSettings">
<option name="DEBUGGING_INFO" value="true" /> <option name="DEBUGGING_INFO" value="true" />
<option name="GENERATE_NO_WARNINGS" value="true" /> <option name="GENERATE_NO_WARNINGS" value="true" />
<option name="DEPRECATION" value="true" /> <option name="DEPRECATION" value="true" />
<option name="ADDITIONAL_OPTIONS_STRING" value="" /> <option name="ADDITIONAL_OPTIONS_STRING" value="" />
<option name="MAXIMUM_HEAP_SIZE" value="128" /> <option name="MAXIMUM_HEAP_SIZE" value="128" />
</component> </component>
<component name="JavadocGenerationManager"> <component name="JavadocGenerationManager">
<option name="OUTPUT_DIRECTORY" value="c:/agent/docs" /> <option name="OUTPUT_DIRECTORY" value="c:/agent/docs" />
<option name="OPTION_SCOPE" value="protected" /> <option name="OPTION_SCOPE" value="protected" />
<option name="OPTION_HIERARCHY" value="true" /> <option name="OPTION_HIERARCHY" value="true" />
<option name="OPTION_NAVIGATOR" value="true" /> <option name="OPTION_NAVIGATOR" value="true" />
<option name="OPTION_INDEX" value="true" /> <option name="OPTION_INDEX" value="true" />
<option name="OPTION_SEPARATE_INDEX" value="true" /> <option name="OPTION_SEPARATE_INDEX" value="true" />
<option name="OPTION_DOCUMENT_TAG_USE" value="false" /> <option name="OPTION_DOCUMENT_TAG_USE" value="false" />
<option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" /> <option name="OPTION_DOCUMENT_TAG_AUTHOR" value="false" />
<option name="OPTION_DOCUMENT_TAG_VERSION" value="false" /> <option name="OPTION_DOCUMENT_TAG_VERSION" value="false" />
<option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" /> <option name="OPTION_DOCUMENT_TAG_DEPRECATED" value="true" />
<option name="OPTION_DEPRECATED_LIST" value="true" /> <option name="OPTION_DEPRECATED_LIST" value="true" />
<option name="OTHER_OPTIONS" /> <option name="OTHER_OPTIONS" />
<option name="HEAP_SIZE" /> <option name="HEAP_SIZE" />
<option name="OPEN_IN_BROWSER" value="true" /> <option name="OPEN_IN_BROWSER" value="true" />
</component> </component>
<component name="JikesSettings"> <component name="JikesSettings">
<option name="JIKES_PATH" value="" /> <option name="JIKES_PATH" value="" />
<option name="DEBUGGING_INFO" value="true" /> <option name="DEBUGGING_INFO" value="true" />
<option name="DEPRECATION" value="true" /> <option name="DEPRECATION" value="true" />
<option name="GENERATE_NO_WARNINGS" value="false" /> <option name="GENERATE_NO_WARNINGS" value="false" />
<option name="IS_EMACS_ERRORS_MODE" value="true" /> <option name="IS_EMACS_ERRORS_MODE" value="true" />
<option name="ADDITIONAL_OPTIONS_STRING" value="" /> <option name="ADDITIONAL_OPTIONS_STRING" value="" />
</component> </component>
<component name="Palette2"> <component name="Palette2">
<group name="Swing"> <group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false"> <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item> </item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false"> <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item> </item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false"> <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item> </item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false"> <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item> </item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false"> <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values> <initial-values>
<property name="text" value="Button" /> <property name="text" value="Button" />
</initial-values> </initial-values>
</item> </item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false"> <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values> <initial-values>
<property name="text" value="RadioButton" /> <property name="text" value="RadioButton" />
</initial-values> </initial-values>
</item> </item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false"> <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values> <initial-values>
<property name="text" value="CheckBox" /> <property name="text" value="CheckBox" />
</initial-values> </initial-values>
</item> </item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false"> <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values> <initial-values>
<property name="text" value="Label" /> <property name="text" value="Label" />
</initial-values> </initial-values>
</item> </item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false"> <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" /> <preferred-size width="150" height="-1" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false"> <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" /> <preferred-size width="150" height="-1" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false"> <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" /> <preferred-size width="150" height="-1" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false"> <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false"> <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false"> <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false"> <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item> </item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false"> <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false"> <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false"> <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" /> <preferred-size width="150" height="50" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false"> <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" /> <preferred-size width="200" height="200" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false"> <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" /> <preferred-size width="200" height="200" />
</default-constraints> </default-constraints>
</item> </item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false"> <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item> </item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false"> <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item> </item>
</group> </group>
</component> </component>
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://C:/code/spark/plugins/fastpath/Fastpath.iml" filepath="C:/code/spark/plugins/fastpath/Fastpath.iml" /> <module fileurl="file://$PROJECT_DIR$/../../plugins/fastpath/Fastpath.iml" filepath="$PROJECT_DIR$/../../plugins/fastpath/Fastpath.iml" />
<module fileurl="file://$PROJECT_DIR$/Spark/Spark.iml" filepath="$PROJECT_DIR$/Spark/Spark.iml" /> <module fileurl="file://$PROJECT_DIR$/Spark/Spark.iml" filepath="$PROJECT_DIR$/Spark/Spark.iml" />
<module fileurl="file://$PROJECT_DIR$/Spark.iml" filepath="$PROJECT_DIR$/Spark.iml" /> <module fileurl="file://$PROJECT_DIR$/Spark/Spark.iml" filepath="$PROJECT_DIR$/Spark/Spark.iml" />
</modules> <module fileurl="file://$PROJECT_DIR$/Spark.iml" filepath="$PROJECT_DIR$/Spark.iml" />
</component> </modules>
<component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="JDK 1.5.0" /> </component>
<component name="RmicSettings"> <component name="ProjectRootManager" version="2" assert-keyword="true" jdk-15="true" project-jdk-name="JDK 1.5.0" />
<option name="IS_EANABLED" value="false" /> <component name="RmicSettings">
<option name="DEBUGGING_INFO" value="true" /> <option name="IS_EANABLED" value="false" />
<option name="GENERATE_NO_WARNINGS" value="false" /> <option name="DEBUGGING_INFO" value="true" />
<option name="GENERATE_IIOP_STUBS" value="false" /> <option name="GENERATE_NO_WARNINGS" value="false" />
<option name="ADDITIONAL_OPTIONS_STRING" value="" /> <option name="GENERATE_IIOP_STUBS" value="false" />
</component> <option name="ADDITIONAL_OPTIONS_STRING" value="" />
<component name="libraryTable" /> </component>
<component name="uidesigner-configuration"> <component name="libraryTable" />
<option name="INSTRUMENT_CLASSES" value="true" /> <component name="uidesigner-configuration">
<option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" /> <option name="INSTRUMENT_CLASSES" value="true" />
</component> <option name="COPY_FORMS_RUNTIME_TO_OUTPUT" value="true" />
<UsedPathMacros /> </component>
</project> <UsedPathMacros />
</project>

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,7 @@ import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form; import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.MessageEventNotificationListener; import org.jivesoftware.smackx.MessageEventNotificationListener;
import org.jivesoftware.smackx.muc.MultiUserChat; import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.spark.component.tabbedPane.SparkTab;
import org.jivesoftware.spark.ui.ChatContainer; import org.jivesoftware.spark.ui.ChatContainer;
import org.jivesoftware.spark.ui.ChatRoom; import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomListener; import org.jivesoftware.spark.ui.ChatRoomListener;
@ -35,16 +36,23 @@ import org.jivesoftware.spark.ui.rooms.GroupChatRoom;
import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.preference.chat.ChatPreference; import org.jivesoftware.sparkimpl.preference.chat.ChatPreference;
import org.jivesoftware.sparkimpl.preference.chat.ChatPreferences; import org.jivesoftware.sparkimpl.preference.chat.ChatPreferences;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
import javax.swing.Icon; import java.awt.Color;
import javax.swing.SwingUtilities; import java.awt.Font;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
/** /**
* Handles the Chat Management of each individual <code>Workspace</code>. The ChatManager is responsible * Handles the Chat Management of each individual <code>Workspace</code>. The ChatManager is responsible
@ -62,11 +70,34 @@ public class ChatManager implements MessageEventNotificationListener {
private Set<String> customList = new HashSet<String>(); private Set<String> customList = new HashSet<String>();
private static ChatManager singleton;
private static final Object LOCK = new Object();
/**
* Returns the singleton instance of <CODE>ChatManager</CODE>,
* creating it if necessary.
* <p/>
*
* @return the singleton instance of <Code>ChatManager</CODE>
*/
public static ChatManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating
// two singletons.
synchronized (LOCK) {
if (null == singleton) {
ChatManager controller = new ChatManager();
singleton = controller;
return controller;
}
}
return singleton;
}
/** /**
* Create a new instance of ChatManager. * Create a new instance of ChatManager.
*/ */
public ChatManager() { private ChatManager() {
chatContainer = new ChatContainer(); chatContainer = new ChatContainer();
// Add a Message Handler // Add a Message Handler
@ -80,6 +111,9 @@ public class ChatManager implements MessageEventNotificationListener {
} }
} }
}, new PacketTypeFilter(Message.class)); }, new PacketTypeFilter(Message.class));
// Start timeout
checkRoomsForTimeout();
} }
@ -383,5 +417,51 @@ public class ChatManager implements MessageEventNotificationListener {
}); });
} }
/**
* Checks every room every 30 seconds to see if it's timed out.
*/
private void checkRoomsForTimeout() {
int delay = 30000; // delay for 5 sec.
int period = 30000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
for (ChatRoom chatRoom : getChatContainer().getChatRooms()) {
long lastActivity = chatRoom.getLastActivity();
long currentTime = System.currentTimeMillis();
long diff = currentTime - lastActivity;
int minutes = (int)(diff / (60 * 1000F));
LocalPreferences pref = SettingsManager.getLocalPreferences();
int timeoutMinutes = pref.getChatLengthDefaultTimeout();
try {
ChatRoom activeChatRoom = getChatContainer().getActiveChatRoom();
if(activeChatRoom == chatRoom){
continue;
}
}
catch (ChatRoomNotFoundException e) {
}
if (timeoutMinutes <= minutes) {
// Turn tab gray
int index = getChatContainer().indexOfComponent(chatRoom);
SparkTab tab = getChatContainer().getTabAt(index);
final JLabel titleLabel = tab.getTitleLabel();
Font oldFont = titleLabel.getFont();
Font newFont = new Font(oldFont.getFontName(), Font.BOLD, oldFont.getSize());
titleLabel.setFont(newFont);
titleLabel.setForeground(Color.gray);
titleLabel.validate();
titleLabel.repaint();
}
}
}
}, delay, period);
}
} }

View File

@ -169,7 +169,7 @@ public final class SparkManager {
*/ */
public static ChatManager getChatManager() { public static ChatManager getChatManager() {
if (chatManager == null) { if (chatManager == null) {
chatManager = new ChatManager(); chatManager = ChatManager.getInstance();
} }
return chatManager; return chatManager;
} }

View File

@ -34,18 +34,6 @@ import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager; import org.jivesoftware.sparkimpl.settings.local.SettingsManager;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
@ -63,6 +51,18 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/** /**
* Contains all <code>ChatRoom</code> objects within Spark. * Contains all <code>ChatRoom</code> objects within Spark.
* *
@ -72,9 +72,11 @@ public class ChatContainer extends SparkTabbedPane implements MessageListener, C
/** /**
* List of all ChatRoom Listeners. * List of all ChatRoom Listeners.
*/ */
private final List chatRoomListeners = new ArrayList(); private final List<ChatRoomListener> chatRoomListeners = new ArrayList<ChatRoomListener>();
private final List<ChatRoom> chatRoomList = new ArrayList<ChatRoom>(); private final List<ChatRoom> chatRoomList = new ArrayList<ChatRoom>();
private final Map presenceMap = new HashMap();
private final Map<String, PacketListener> presenceMap = new HashMap<String, PacketListener>();
private static final String WELCOME_TITLE = SparkRes.getString(SparkRes.WELCOME); private static final String WELCOME_TITLE = SparkRes.getString(SparkRes.WELCOME);
@ -277,7 +279,6 @@ public class ChatContainer extends SparkTabbedPane implements MessageListener, C
// Change tab icon // Change tab icon
if (chatRoom instanceof ChatRoomImpl) { if (chatRoom instanceof ChatRoomImpl) {
StatusItem statusItem = SparkManager.getWorkspace().getStatusBar().getItemFromPresence(p); StatusItem statusItem = SparkManager.getWorkspace().getStatusBar().getItemFromPresence(p);
Roster roster = SparkManager.getConnection().getRoster();
Icon tabIcon = null; Icon tabIcon = null;
if (statusItem == null && p == null) { if (statusItem == null && p == null) {
tabIcon = SparkRes.getImageIcon(SparkRes.CLEAR_BALL_ICON); tabIcon = SparkRes.getImageIcon(SparkRes.CLEAR_BALL_ICON);
@ -690,7 +691,7 @@ public class ChatContainer extends SparkTabbedPane implements MessageListener, C
} }
final int ok = JOptionPane.showConfirmDialog(SparkManager.getMainWindow(), message, final int ok = JOptionPane.showConfirmDialog(SparkManager.getMainWindow(), message,
"Confirmation", JOptionPane.YES_NO_OPTION); "Confirmation", JOptionPane.YES_NO_OPTION);
if (ok == JOptionPane.OK_OPTION) { if (ok == JOptionPane.OK_OPTION) {
room.closeChatRoom(); room.closeChatRoom();
return; return;
@ -885,10 +886,9 @@ public class ChatContainer extends SparkTabbedPane implements MessageListener, C
final int index = indexOfComponent(room); final int index = indexOfComponent(room);
if (index != -1) { if (index != -1) {
SparkTab tab = getTabAt(index); SparkTab tab = getTabAt(index);
Font font = tab.getTitleLabel().getFont();
final JLabel titleLabel = tab.getTitleLabel(); final JLabel titleLabel = tab.getTitleLabel();
Font newFont = font.deriveFont(Font.BOLD); Font oldFont = titleLabel.getFont();
Font newFont = new Font(oldFont.getFontName(), Font.BOLD, oldFont.getSize());
titleLabel.setFont(newFont); titleLabel.setFont(newFont);
titleLabel.setForeground(Color.red); titleLabel.setForeground(Color.red);
} }

View File

@ -25,6 +25,25 @@ import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.preference.chat.ChatPreference; import org.jivesoftware.sparkimpl.preference.chat.ChatPreference;
import org.jivesoftware.sparkimpl.preference.chat.ChatPreferences; import org.jivesoftware.sparkimpl.preference.chat.ChatPreferences;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.Icon; import javax.swing.Icon;
@ -45,25 +64,6 @@ import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import javax.swing.text.Document; import javax.swing.text.Document;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/** /**
* The base implementation of all ChatRoom conversations. You would implement this class to have most types of Chat. * The base implementation of all ChatRoom conversations. You would implement this class to have most types of Chat.
*/ */
@ -248,7 +248,7 @@ public abstract class ChatRoom extends BackgroundPanel implements ActionListener
getChatInputEditor().getActionMap().put("closeTheRoom", new AbstractAction("closeTheRoom") { getChatInputEditor().getActionMap().put("closeTheRoom", new AbstractAction("closeTheRoom") {
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
final int ok = JOptionPane.showConfirmDialog(SparkManager.getMainWindow(), "Would you like to close this chat?", final int ok = JOptionPane.showConfirmDialog(SparkManager.getMainWindow(), "Would you like to close this chat?",
"Confirmation", JOptionPane.YES_NO_OPTION); "Confirmation", JOptionPane.YES_NO_OPTION);
if (ok == JOptionPane.OK_OPTION) { if (ok == JOptionPane.OK_OPTION) {
// Leave this chat. // Leave this chat.
closeChatRoom(); closeChatRoom();
@ -424,7 +424,7 @@ public abstract class ChatRoom extends BackgroundPanel implements ActionListener
private void checkForEnter(KeyEvent e) { private void checkForEnter(KeyEvent e) {
final KeyStroke keyStroke = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers()); final KeyStroke keyStroke = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
if (!keyStroke.equals(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK)) && if (!keyStroke.equals(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK)) &&
e.getKeyChar() == KeyEvent.VK_ENTER) { e.getKeyChar() == KeyEvent.VK_ENTER) {
e.consume(); e.consume();
sendMessage(); sendMessage();
getChatInputEditor().setText(""); getChatInputEditor().setText("");
@ -869,6 +869,14 @@ public abstract class ChatRoom extends BackgroundPanel implements ActionListener
public JSplitPane getVerticalSlipPane() { public JSplitPane getVerticalSlipPane() {
return verticalSplit; return verticalSplit;
} }
/**
* Implementation of this method should return the last time this chat room
* sent or recieved a message.
*
* @return the last time (in system milliseconds) that the room last recieved a message.
*/
public abstract long getLastActivity();
} }

View File

@ -39,11 +39,6 @@ import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log; import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.profile.VCardManager; import org.jivesoftware.sparkimpl.profile.VCardManager;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.Insets; import java.awt.Insets;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -55,6 +50,11 @@ import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
/** /**
* This is the Person to Person implementation of <code>ChatRoom</code> * This is the Person to Person implementation of <code>ChatRoom</code>
* This room only allows for 1 to 1 conversations. * This room only allows for 1 to 1 conversations.
@ -85,6 +85,8 @@ public class ChatRoomImpl extends ChatRoom {
private boolean sendTypingNotification; private boolean sendTypingNotification;
private String threadID; private String threadID;
private long lastActivity;
/** /**
* Constructs a 1-to-1 ChatRoom. * Constructs a 1-to-1 ChatRoom.
@ -231,6 +233,8 @@ public class ChatRoomImpl extends ChatRoom {
}; };
worker.start(); worker.start();
lastActivity = System.currentTimeMillis();
} }
private void scrollOnTimer() { private void scrollOnTimer() {
@ -341,6 +345,8 @@ public class ChatRoomImpl extends ChatRoom {
catch (Exception ex) { catch (Exception ex) {
Log.error("Error sending message", ex); Log.error("Error sending message", ex);
} }
lastActivity = System.currentTimeMillis();
} }
public String getRoomname() { public String getRoomname() {
@ -421,6 +427,8 @@ public class ChatRoomImpl extends ChatRoom {
} }
} }
else if (packet instanceof Message) { else if (packet instanceof Message) {
lastActivity = System.currentTimeMillis();
// Do something with the incoming packet here. // Do something with the incoming packet here.
final Message message = (Message)packet; final Message message = (Message)packet;
if (message.getError() != null) { if (message.getError() != null) {
@ -571,5 +579,9 @@ public class ChatRoomImpl extends ChatRoom {
} }
public long getLastActivity() {
return lastActivity;
}
} }

View File

@ -88,6 +88,8 @@ public final class GroupChatRoom extends ChatRoom {
private ConferenceRoomInfo roomInfo; private ConferenceRoomInfo roomInfo;
private long lastActivity;
/** /**
* Creates a GroupChatRoom from a <code>MultiUserChat</code>. * Creates a GroupChatRoom from a <code>MultiUserChat</code>.
* *
@ -219,6 +221,9 @@ public final class GroupChatRoom extends ChatRoom {
messageManager = new ChatRoomMessageManager(); messageManager = new ChatRoomMessageManager();
// set last activity to be right now
lastActivity = System.currentTimeMillis();
} }
/** /**
@ -291,6 +296,8 @@ public final class GroupChatRoom extends ChatRoom {
getChatInputEditor().setCaretPosition(0); getChatInputEditor().setCaretPosition(0);
getChatInputEditor().requestFocusInWindow(); getChatInputEditor().requestFocusInWindow();
scrollToBottom(); scrollToBottom();
lastActivity = System.currentTimeMillis();
} }
/** /**
@ -329,6 +336,8 @@ public final class GroupChatRoom extends ChatRoom {
getChatInputEditor().setCaretPosition(0); getChatInputEditor().setCaretPosition(0);
getChatInputEditor().requestFocusInWindow(); getChatInputEditor().requestFocusInWindow();
scrollToBottom(); scrollToBottom();
lastActivity = System.currentTimeMillis();
} }
/** /**
@ -497,6 +506,9 @@ public final class GroupChatRoom extends ChatRoom {
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { public void run() {
handleMessagePacket(packet); handleMessagePacket(packet);
// Set last activity
lastActivity = System.currentTimeMillis();
} }
}); });
@ -967,4 +979,8 @@ public final class GroupChatRoom extends ChatRoom {
public ConferenceRoomInfo getConferenceRoomInfo() { public ConferenceRoomInfo getConferenceRoomInfo() {
return roomInfo; return roomInfo;
} }
public long getLastActivity(){
return lastActivity;
}
} }

View File

@ -84,6 +84,8 @@ public class ChatPreference implements Preference {
panel.setSpellCheckerOn(spellCheckerOn); panel.setSpellCheckerOn(spellCheckerOn);
panel.setGroupChatNotificationsOn(notificationsOn); panel.setGroupChatNotificationsOn(notificationsOn);
panel.setChatHistoryHidden(chatHistoryHidden); panel.setChatHistoryHidden(chatHistoryHidden);
panel.setChatTimeoutTime(localPreferences.getChatLengthDefaultTimeout());
} }
}; };
@ -97,6 +99,7 @@ public class ChatPreference implements Preference {
pref.setSpellCheckerEnabled(panel.isSpellCheckerOn()); pref.setSpellCheckerEnabled(panel.isSpellCheckerOn());
pref.setChatRoomNotifications(panel.isGroupChatNotificationsOn()); pref.setChatRoomNotifications(panel.isGroupChatNotificationsOn());
pref.setChatHistoryEnabled(!panel.isChatHistoryHidden()); pref.setChatHistoryEnabled(!panel.isChatHistoryHidden());
pref.setChatLengthDefaultTimeout(panel.getChatTimeoutTime());
SettingsManager.saveSettings(); SettingsManager.saveSettings();
@ -107,7 +110,7 @@ public class ChatPreference implements Preference {
} }
catch (XMPPException passwordEx) { catch (XMPPException passwordEx) {
JOptionPane.showMessageDialog(SparkManager.getMainWindow(), "Unable to change password. Please see your server admin.", JOptionPane.showMessageDialog(SparkManager.getMainWindow(), "Unable to change password. Please see your server admin.",
"Password Change Error", JOptionPane.ERROR_MESSAGE); "Password Change Error", JOptionPane.ERROR_MESSAGE);
Log.error("Unable to change password", passwordEx); Log.error("Unable to change password", passwordEx);
} }
} }

View File

@ -27,6 +27,7 @@ import javax.swing.JLabel;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JPasswordField; import javax.swing.JPasswordField;
import javax.swing.JTextField;
/** /**
* The Preference UI used to handle changing of Chat Preferences. * The Preference UI used to handle changing of Chat Preferences.
@ -45,6 +46,8 @@ public class ChatPreferencePanel extends JPanel implements ActionListener {
private JLabel passwordLabel = new JLabel(); private JLabel passwordLabel = new JLabel();
private JLabel confirmationPasswordLabel = new JLabel(); private JLabel confirmationPasswordLabel = new JLabel();
private JCheckBox hideChatHistory = new JCheckBox(); private JCheckBox hideChatHistory = new JCheckBox();
private JTextField chatTimeoutField = new JTextField();
/** /**
* Constructor invokes UI setup. * Constructor invokes UI setup.
@ -79,6 +82,12 @@ public class ChatPreferencePanel extends JPanel implements ActionListener {
chatWindowPanel.add(spellCheckBox, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); chatWindowPanel.add(spellCheckBox, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
chatWindowPanel.add(groupChatNotificationBox, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); chatWindowPanel.add(groupChatNotificationBox, new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
chatWindowPanel.add(hideChatHistory, new GridBagConstraints(0, 3, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); chatWindowPanel.add(hideChatHistory, new GridBagConstraints(0, 3, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
chatWindowPanel.add(hideChatHistory, new GridBagConstraints(0, 3, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
JLabel chatTimeoutLabel = new JLabel();
ResourceUtils.resLabel(chatTimeoutLabel, chatTimeoutField, "&Inactive chats expire after (min):");
chatWindowPanel.add(chatTimeoutLabel, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
chatWindowPanel.add(chatTimeoutField, new GridBagConstraints(1, 4, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 50, 0));
generalPanel.add(passwordLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0)); generalPanel.add(passwordLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
@ -150,6 +159,19 @@ public class ChatPreferencePanel extends JPanel implements ActionListener {
return hideChatHistory.isSelected(); return hideChatHistory.isSelected();
} }
public void setChatTimeoutTime(int time) {
chatTimeoutField.setText(Integer.toString(time));
}
public int getChatTimeoutTime() {
try {
return Integer.parseInt(chatTimeoutField.getText());
}
catch (NumberFormatException e) {
return 15;
}
}
public void actionPerformed(ActionEvent actionEvent) { public void actionPerformed(ActionEvent actionEvent) {
if (hideChatHistory.isSelected()) { if (hideChatHistory.isSelected()) {
int ok = JOptionPane.showConfirmDialog(this, "Delete all previous history?", "Delete Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); int ok = JOptionPane.showConfirmDialog(this, "Delete all previous history?", "Delete Confirmation", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);

View File

@ -407,6 +407,14 @@ public class LocalPreferences {
props.setProperty("fileTransferTimeout", Integer.toString(minutes)); props.setProperty("fileTransferTimeout", Integer.toString(minutes));
} }
public void setChatLengthDefaultTimeout(int minutes) {
props.setProperty("defaultChatLengthTimeout", Integer.toString(minutes));
}
public int getChatLengthDefaultTimeout() {
return Integer.parseInt(props.getProperty("defaultChatLengthTimeout", "15"));
}
private boolean getBoolean(String property, boolean defaultValue) { private boolean getBoolean(String property, boolean defaultValue) {
return Boolean.parseBoolean(props.getProperty(property, Boolean.toString(defaultValue))); return Boolean.parseBoolean(props.getProperty(property, Boolean.toString(defaultValue)));
} }