@ -0,0 +1 @@
|
||||
api
|
||||
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>lib</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,54 @@
|
||||
############################################################
|
||||
# Default Logging Configuration File
|
||||
#
|
||||
# You can use a different file by specifying a filename
|
||||
# with the java.util.logging.config.file system property.
|
||||
# For example java -Djava.util.logging.config.file=myfile
|
||||
############################################################
|
||||
|
||||
############################################################
|
||||
# Global properties
|
||||
############################################################
|
||||
|
||||
# "handlers" specifies a comma separated list of log Handler
|
||||
# classes. These handlers will be installed during VM startup.
|
||||
# Note that these classes must be on the system classpath.
|
||||
# By default we only configure a ConsoleHandler, which will only
|
||||
# show messages at the INFO and above levels.
|
||||
handlers= java.util.logging.ConsoleHandler
|
||||
|
||||
# To also add the FileHandler, use the following line instead.
|
||||
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
|
||||
|
||||
# Default global logging level.
|
||||
# This specifies which kinds of events are logged across
|
||||
# all loggers. For any given facility this global level
|
||||
# can be overriden by a facility specific level
|
||||
# Note that the ConsoleHandler also has a separate level
|
||||
# setting to limit messages printed to the console.
|
||||
.level= FINE
|
||||
|
||||
############################################################
|
||||
# Handler specific properties.
|
||||
# Describes specific configuration info for Handlers.
|
||||
############################################################
|
||||
|
||||
# default file output is in user's home directory.
|
||||
java.util.logging.FileHandler.pattern = %h/java%u.log
|
||||
java.util.logging.FileHandler.limit = 50000
|
||||
java.util.logging.FileHandler.count = 1
|
||||
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
|
||||
|
||||
# Limit the message that are printed on the console to FINE and above.
|
||||
java.util.logging.ConsoleHandler.level = FINEST
|
||||
java.util.logging.ConsoleHandler.formatter = net.java.sip.communicator.util.ScLogFormatter
|
||||
|
||||
|
||||
############################################################
|
||||
# Facility specific properties.
|
||||
# Provides extra control for each logger.
|
||||
############################################################
|
||||
|
||||
# For example, set the com.xyz.foo logger to only log SEVERE
|
||||
# messages:
|
||||
com.xyz.foo.level = SEVERE
|
||||
@ -0,0 +1,67 @@
|
||||
#
|
||||
# Framework config properties.
|
||||
#
|
||||
org.osgi.framework.system.packages= org.osgi.framework; \
|
||||
javax.swing;\
|
||||
javax.swing.event;\
|
||||
javax.swing.table;\
|
||||
javax.swing.text; \
|
||||
javax.accessibility; \
|
||||
javax.swing.plaf; \
|
||||
javax.swing.tree; \
|
||||
javax.swing.undo; \
|
||||
javax.swing.event; \
|
||||
javax.swing.border; \
|
||||
org.w3c.dom;\
|
||||
org.xml.sax;\
|
||||
javax.xml.parsers;\
|
||||
org.jaxen; \
|
||||
org.jaxen.dom; \
|
||||
org.jaxen.saxpath; \
|
||||
org.apache.xml.serializer;\
|
||||
javax.xml.transform;\
|
||||
javax.xml.transform.dom;\
|
||||
javax.xml.transform.stream;\
|
||||
javax.media;\
|
||||
javax.media.format;\
|
||||
javax.media.protocol;\
|
||||
net.java.stun4j;\
|
||||
net.java.stun4j.client;\
|
||||
net.java.stun4j.StunAddress;\
|
||||
net.java.stun4j.StunException;
|
||||
|
||||
oscar.auto.start.1= \
|
||||
file:lib/bundle/shell.jar \
|
||||
file:lib/bundle/bundlerepository.jar \
|
||||
file:lib/bundle/servicebinder.jar \
|
||||
file:lib/bundle/tablelayout.jar
|
||||
|
||||
oscar.auto.start.2= \
|
||||
file:sc-bundles/util.jar
|
||||
|
||||
oscar.auto.start.3= \
|
||||
file:sc-bundles/configuration.jar \
|
||||
file:sc-bundles/media.jar \
|
||||
file:sc-bundles/netaddr.jar
|
||||
|
||||
oscar.auto.start.4= \
|
||||
file:sc-bundles/resources.jar \
|
||||
file:sc-bundles/history.jar
|
||||
|
||||
# Uncomment the following lines if you want to run the architect viewer
|
||||
# bundle.
|
||||
#oscar.auto.start.100= \
|
||||
# file:lib/bundle/architectureviewer1.1.jar
|
||||
|
||||
#Specify the directory where oscar should deploy its bundles
|
||||
oscar.cache.profiledir=sip-communicator.bin
|
||||
|
||||
|
||||
oscar.startlevel.framework=100
|
||||
oscar.startlevel.bundle=100
|
||||
#
|
||||
# Bundle config properties.
|
||||
#
|
||||
#org.osgi.service.http.port=8080
|
||||
#osgi.shell.telnet=on
|
||||
#oscar.repository.url=file:/home/rickhall/projects/noscar/repository.xml
|
||||
@ -0,0 +1,79 @@
|
||||
#
|
||||
# Oscar configuration properties.
|
||||
# This file configures the OSCAR framework to run sip-communicator unit tests
|
||||
# and Service Implementation Compatibility Kits
|
||||
#
|
||||
org.osgi.framework.system.packages= org.osgi.framework; \
|
||||
javax.swing; \
|
||||
javax.swing.event; \
|
||||
javax.swing.table; \
|
||||
org.w3c.dom; \
|
||||
org.xml.sax; \
|
||||
javax.xml.parsers;\
|
||||
org.jaxen; \
|
||||
org.jaxen.dom; \
|
||||
org.jaxen.saxpath; \
|
||||
org.apache.xml.serializer;\
|
||||
javax.xml.transform;\
|
||||
javax.xml.transform.dom;\
|
||||
javax.xml.transform.stream;\
|
||||
javax.media;\
|
||||
javax.media.format;\
|
||||
javax.media.protocol;\
|
||||
javax.sound.sampled;\
|
||||
com.sun.media.protocol.javasound;\
|
||||
com.sun.media.protocol.v4l;\
|
||||
net.java.stun4j; \
|
||||
net.java.stun4j.StunAddress;\
|
||||
net.java.stun4j.StunException;\
|
||||
net.java.stun4j.client;\
|
||||
org.apache.tools.ant.taskdefs.optional.junit;
|
||||
|
||||
|
||||
#
|
||||
# In case you want testing to run using oscar's graphical ui then uncomment
|
||||
#
|
||||
# the following and copy/paste them after the shell.jar bundle
|
||||
# file:lib/bundle/shellgui.jar \
|
||||
# file:lib/bundle/shellplugin.jar \
|
||||
# file:lib/bundle/tablelayout.jar \
|
||||
#
|
||||
|
||||
oscar.auto.start.1= \
|
||||
file:lib/bundle/shell.jar \
|
||||
file:lib/bundle/bundlerepository.jar \
|
||||
file:lib/bundle/servicebinder.jar \
|
||||
file:lib/bundle/junit.jar
|
||||
|
||||
oscar.auto.start.2= \
|
||||
file:sc-bundles/util.jar
|
||||
|
||||
oscar.auto.start.3= \
|
||||
file:sc-bundles/configuration.jar \
|
||||
file:sc-bundles/media.jar \
|
||||
file:sc-bundles/netaddr.jar
|
||||
|
||||
oscar.auto.start.4= \
|
||||
file:sc-bundles/protocol-sip.jar \
|
||||
file:sc-bundles/resources.jar \
|
||||
file:sc-bundles/history.jar
|
||||
|
||||
oscar.auto.start.5= \
|
||||
file:sc-bundles/slickless.jar \
|
||||
file:sc-bundles/configuration-slick.jar \
|
||||
file:sc-bundles/media-slick.jar \
|
||||
file:sc-bundles/netaddr-slick.jar \
|
||||
file:sc-bundles/resources-slick.jar \
|
||||
file:sc-bundles/history-slick.jar
|
||||
|
||||
|
||||
oscar.auto.start.100= \
|
||||
file:sc-bundles/slick-runner.jar
|
||||
|
||||
#Specify the directory where oscar should deploy its bundles
|
||||
oscar.cache.profiledir=sip-communicator.utest.bin
|
||||
|
||||
oscar.startlevel.framework=100
|
||||
oscar.startlevel.bundle=100
|
||||
|
||||
oscar.embedded.execution=true
|
||||
@ -0,0 +1 @@
|
||||
sick
|
||||
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.configuration;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.util.Logger;
|
||||
import java.io.*;
|
||||
import net.java.sip.communicator.util.xml.*;
|
||||
import net.java.sip.communicator.impl.configuration.xml.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class Activator
|
||||
implements BundleActivator
|
||||
{
|
||||
private Logger logger = Logger.getLogger(ConfigurationServiceImpl.class);
|
||||
private ConfigurationServiceImpl impl = new ConfigurationServiceImpl();
|
||||
|
||||
/**
|
||||
* Starts the configuration service
|
||||
*
|
||||
* @param bundleContext the BundleContext as provided from the osgi
|
||||
* framework.
|
||||
* @throws Exception if anything goes wrong
|
||||
*/
|
||||
public void start(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
bundleContext.registerService( ConfigurationService.class.getName(),
|
||||
impl,
|
||||
new java.util.Hashtable() );
|
||||
|
||||
logger.debug("Successfully registered " + getClass().getName());
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the configuration service to store the properties object and
|
||||
* unregisters the configuration servcice.
|
||||
*
|
||||
* @param bundlecontext BundleContext
|
||||
* @throws Exception
|
||||
* @todo Implement this org.osgi.framework.BundleActivator method
|
||||
*/
|
||||
public void stop(BundleContext bundlecontext) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
|
||||
|
||||
logger.info("The ConfigurationService stop method has been called.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,433 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.configuration;
|
||||
|
||||
import net.java.sip.communicator.service.configuration.event.*;
|
||||
import java.util.*;
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.util.xml.*;
|
||||
import net.java.sip.communicator.impl.configuration.xml.*;
|
||||
|
||||
/**
|
||||
* This is a utility class that can be used by objects that support constrained
|
||||
* properties. You can use an instance of this class as a member field and
|
||||
* delegate various work to it.
|
||||
*
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class ChangeEventDispatcher
|
||||
{
|
||||
|
||||
/**
|
||||
* All property change listeners registered so far.
|
||||
*/
|
||||
private Vector propertyChangeListeners;
|
||||
|
||||
/**
|
||||
* All listeners registered for vetoable change events.
|
||||
*/
|
||||
private Vector vetoableChangeListeners;
|
||||
|
||||
/**
|
||||
* Hashtable for managing property change listeners registered for specific
|
||||
* properties. Maps property names to PropertyChangeSupport objects.
|
||||
*/
|
||||
private Hashtable propertyChangeChildren;
|
||||
|
||||
/**
|
||||
* Hashtable for managing vetoable change listeners registered for specific
|
||||
* properties. Maps property names to PropertyChangeSupport objects.
|
||||
*/
|
||||
private Hashtable vetoableChangeChildren;
|
||||
|
||||
/**
|
||||
* The object to be provided as the "source" for any generated events.
|
||||
*/
|
||||
private Object source;
|
||||
|
||||
/**
|
||||
* Constructs a <code>VetoableChangeSupport</code> object.
|
||||
*
|
||||
* @param sourceObject The object to be given as the source for any events.
|
||||
*/
|
||||
public ChangeEventDispatcher(Object sourceObject)
|
||||
{
|
||||
if (sourceObject == null)
|
||||
{
|
||||
throw new NullPointerException();
|
||||
}
|
||||
source = sourceObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a PropertyChangeListener to the listener list.
|
||||
* The listener is registered for all properties.
|
||||
*
|
||||
* @param listener The PropertyChangeChangeListener to be added
|
||||
*/
|
||||
public synchronized void addPropertyChangeListener(
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
if (propertyChangeListeners == null)
|
||||
{
|
||||
propertyChangeListeners = new Vector();
|
||||
}
|
||||
|
||||
propertyChangeListeners.addElement(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a PropertyChangeListener for a specific property. The listener
|
||||
* will be invoked only when a call on firePropertyChange names that
|
||||
* specific property.
|
||||
*
|
||||
* @param propertyName The name of the property to listen on.
|
||||
* @param listener The ConfigurationChangeListener to be added
|
||||
*/
|
||||
|
||||
public synchronized void addPropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
if (propertyChangeChildren == null)
|
||||
{
|
||||
propertyChangeChildren = new Hashtable();
|
||||
}
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher) propertyChangeChildren.get(
|
||||
propertyName);
|
||||
if (child == null)
|
||||
{
|
||||
child = new ChangeEventDispatcher(source);
|
||||
propertyChangeChildren.put(propertyName, child);
|
||||
}
|
||||
child.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a PropertyChangeListener from the listener list.
|
||||
* This removes a ConfigurationChangeListener that was registered
|
||||
* for all properties.
|
||||
*
|
||||
* @param listener The PropertyChangeListener to be removed
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
|
||||
if (propertyChangeListeners == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
propertyChangeListeners.removeElement(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a PropertyChangeListener for a specific property.
|
||||
*
|
||||
* @param propertyName The name of the property that was listened on.
|
||||
* @param listener The VetoableChangeListener to be removed
|
||||
*/
|
||||
public synchronized void removePropertyChangeListener(
|
||||
String propertyName,
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
if (propertyChangeChildren == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher)
|
||||
propertyChangeChildren.get( propertyName );
|
||||
|
||||
if (child == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
child.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a VetoableChangeListener to the listener list.
|
||||
* The listener is registered for all properties.
|
||||
*
|
||||
* @param listener The VetoableChangeListener to be added
|
||||
*/
|
||||
public synchronized void addVetoableChangeListener(
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
if (vetoableChangeListeners == null)
|
||||
{
|
||||
vetoableChangeListeners = new Vector();
|
||||
}
|
||||
|
||||
vetoableChangeListeners.addElement(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a VetoableChangeListener from the listener list.
|
||||
* This removes a VetoableChangeListener that was registered
|
||||
* for all properties.
|
||||
*
|
||||
* @param listener The VetoableChangeListener to be removed
|
||||
*/
|
||||
public synchronized void removeVetoableChangeListener(
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
|
||||
if (vetoableChangeListeners == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
vetoableChangeListeners.removeElement(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a VetoableChangeListener for a specific property. The listener
|
||||
* will be invoked only when a call on fireVetoableChange names that
|
||||
* specific property.
|
||||
*
|
||||
* @param propertyName The name of the property to listen on.
|
||||
* @param listener The ConfigurationChangeListener to be added
|
||||
*/
|
||||
|
||||
public synchronized void addVetoableChangeListener(
|
||||
String propertyName,
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
if (vetoableChangeChildren == null)
|
||||
{
|
||||
vetoableChangeChildren = new Hashtable();
|
||||
}
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher) vetoableChangeChildren.get(
|
||||
propertyName);
|
||||
if (child == null)
|
||||
{
|
||||
child = new ChangeEventDispatcher(source);
|
||||
vetoableChangeChildren.put(propertyName, child);
|
||||
}
|
||||
child.addVetoableChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a VetoableChangeListener for a specific property.
|
||||
*
|
||||
* @param propertyName The name of the property that was listened on.
|
||||
* @param listener The VetoableChangeListener to be removed
|
||||
*/
|
||||
public synchronized void removeVetoableChangeListener(
|
||||
String propertyName,
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
if (vetoableChangeChildren == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher)
|
||||
vetoableChangeChildren.get( propertyName );
|
||||
|
||||
if (child == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
child.removeVetoableChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a vetoable property update to any registered listeners. If
|
||||
* no one vetos the change, then fire a new ConfigurationChangeEvent
|
||||
* indicating that the change has been accepted. In the case of a
|
||||
* PropertyVetoException, end eventdispatch and rethrow the eception
|
||||
* <p>
|
||||
* No event is fired if old and new are equal and non-null.
|
||||
*
|
||||
* @param propertyName The programmatic name of the property
|
||||
* that is about to change..
|
||||
* @param oldValue The old value of the property.
|
||||
* @param newValue The new value of the property.
|
||||
* @exception PropertyVetoException if the recipient wishes the property
|
||||
* change to be rolled back.
|
||||
*/
|
||||
public void fireVetoableChange(String propertyName,
|
||||
Object oldValue, Object newValue) throws
|
||||
PropertyVetoException
|
||||
{
|
||||
if (vetoableChangeListeners == null && vetoableChangeChildren == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PropertyChangeEvent evt = new PropertyChangeEvent(source,
|
||||
propertyName, oldValue, newValue);
|
||||
fireVetoableChange(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire a vetoable property update to any registered listeners. If
|
||||
* anyone vetos the change, then the excption will be rethrown by this
|
||||
* method.
|
||||
* <p>
|
||||
* No event is fired if old and new are equal and non-null.
|
||||
*
|
||||
* @param evt The PropertyChangeEvent to be fired.
|
||||
* @exception PropertyVetoException if at least one of the recipients has
|
||||
* vetoed the change.
|
||||
*/
|
||||
public void fireVetoableChange(PropertyChangeEvent evt) throws
|
||||
PropertyVetoException
|
||||
{
|
||||
|
||||
Object oldValue = evt.getOldValue();
|
||||
Object newValue = evt.getNewValue();
|
||||
String propertyName = evt.getPropertyName();
|
||||
if (oldValue != null && newValue != null && oldValue.equals(newValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Vector targets = null;
|
||||
ChangeEventDispatcher child = null;
|
||||
synchronized (this)
|
||||
{
|
||||
if (vetoableChangeListeners != null)
|
||||
{
|
||||
targets = (Vector) vetoableChangeListeners.clone();
|
||||
}
|
||||
if (vetoableChangeChildren != null && propertyName != null)
|
||||
{
|
||||
child = (ChangeEventDispatcher)vetoableChangeChildren.get(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
if (vetoableChangeListeners != null)
|
||||
{
|
||||
for (int i = 0; i < targets.size(); i++)
|
||||
{
|
||||
VetoableChangeListener target =
|
||||
(VetoableChangeListener) targets.elementAt(i);
|
||||
//don't catch the exception - let it bounce to the caller.
|
||||
target.vetoableChange(evt);
|
||||
}
|
||||
}
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
child.fireVetoableChange(evt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Report a bound property update to any registered listeners.
|
||||
* No event is fired if old and new are equal and non-null.
|
||||
*
|
||||
* @param propertyName The programmatic name of the property
|
||||
* that was changed.
|
||||
* @param oldValue The old value of the property.
|
||||
* @param newValue The new value of the property.
|
||||
*/
|
||||
public void firePropertyChange(String propertyName,
|
||||
Object oldValue, Object newValue)
|
||||
{
|
||||
if (oldValue != null && newValue != null && oldValue.equals(newValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
firePropertyChange(new PropertyChangeEvent(source, propertyName,
|
||||
oldValue, newValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an existing PropertyChangeEvent to any registered listeners.
|
||||
* No event is fired if the given event's old and new values are
|
||||
* equal and non-null.
|
||||
* @param evt The PropertyChangeEvent object.
|
||||
*/
|
||||
public void firePropertyChange(PropertyChangeEvent evt)
|
||||
{
|
||||
Object oldValue = evt.getOldValue();
|
||||
Object newValue = evt.getNewValue();
|
||||
String propertyName = evt.getPropertyName();
|
||||
if (oldValue != null && newValue != null && oldValue.equals(newValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyChangeListeners != null)
|
||||
{
|
||||
Iterator iterator = propertyChangeListeners.iterator();
|
||||
while (iterator.hasNext())
|
||||
{
|
||||
PropertyChangeListener target =
|
||||
(PropertyChangeListener) iterator.next();
|
||||
target.propertyChange(evt);
|
||||
}
|
||||
}
|
||||
|
||||
if (propertyChangeChildren != null && propertyName != null)
|
||||
{
|
||||
ChangeEventDispatcher child = null;
|
||||
child = (ChangeEventDispatcher) propertyChangeChildren.get(propertyName);
|
||||
if (child != null)
|
||||
{
|
||||
child.firePropertyChange(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any listeners for a specific property. (Generic
|
||||
* listeners count as well)
|
||||
*
|
||||
* @param propertyName the property name.
|
||||
* @return true if there are one or more listeners for the given property
|
||||
*/
|
||||
public synchronized boolean hasPropertyChangeListeners(String propertyName)
|
||||
{
|
||||
if(propertyChangeListeners != null && !propertyChangeListeners.isEmpty())
|
||||
{
|
||||
// there is a generic listener
|
||||
return true;
|
||||
}
|
||||
if (propertyChangeChildren != null)
|
||||
{
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher) propertyChangeChildren.get(
|
||||
propertyName);
|
||||
if (child != null && child.propertyChangeListeners != null)
|
||||
{
|
||||
return!child.propertyChangeListeners.isEmpty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any vetoable change listeners for a specific property.
|
||||
* (Generic vetoable change listeners count as well)
|
||||
*
|
||||
* @param propertyName the property name.
|
||||
* @return true if there are one or more listeners for the given property
|
||||
*/
|
||||
public synchronized boolean hasVetoableChangeListeners(String propertyName)
|
||||
{
|
||||
if(vetoableChangeListeners != null && !vetoableChangeListeners.isEmpty())
|
||||
{
|
||||
// there is a generic listener
|
||||
return true;
|
||||
}
|
||||
if (vetoableChangeChildren != null)
|
||||
{
|
||||
ChangeEventDispatcher child = (ChangeEventDispatcher)
|
||||
vetoableChangeChildren.get(propertyName);
|
||||
|
||||
if (child != null && child.vetoableChangeListeners != null)
|
||||
{
|
||||
return!child.vetoableChangeListeners.isEmpty();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,846 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.configuration;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import javax.xml.parsers.*;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import org.xml.sax.*;
|
||||
import net.java.sip.communicator.impl.configuration.xml.*;
|
||||
import net.java.sip.communicator.service.configuration.*;
|
||||
import net.java.sip.communicator.service.configuration.event.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.java.sip.communicator.util.xml.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A straight forward implementation of the ConfigurationService using an xml
|
||||
* file for storing properties. Currently only String properties are
|
||||
* meaningfully saved (we should probably consider how and whether we should
|
||||
* take care of the rest).
|
||||
*
|
||||
* @author Emil Ivov
|
||||
* @author Damian Minkov
|
||||
*/
|
||||
public class ConfigurationServiceImpl
|
||||
implements ConfigurationService
|
||||
{
|
||||
private Logger logger = Logger.getLogger(ConfigurationServiceImpl.class);
|
||||
|
||||
/**
|
||||
* The XML Document containing the configuration file this service loaded.
|
||||
*/
|
||||
private Document propertiesDocument = null;
|
||||
|
||||
/** Name of the xml attribute containing property values */
|
||||
private static final String ATTRIBUTE_VALUE = "value";
|
||||
|
||||
/**
|
||||
* Name of the xml attribute indicating that a property is to be resolved
|
||||
* in the system properties
|
||||
*/
|
||||
private static final String SYSTEM_ATTRIBUTE_NAME = "system";
|
||||
|
||||
/** The value of the Name of the xml attribute containing property values */
|
||||
private static final String SYSTEM_ATTRIBUTE_TRUE = "true";
|
||||
|
||||
/**
|
||||
* The name of the system property that stores the name of the configuration
|
||||
* file.
|
||||
*/
|
||||
private static final String FILE_NAME_PROPERTY =
|
||||
"net.java.sip.communicator.PROPERTIES_FILE_NAME";
|
||||
|
||||
/**
|
||||
* Our event dispatcher.
|
||||
*/
|
||||
private ChangeEventDispatcher changeEventDispatcher =
|
||||
new ChangeEventDispatcher(this);
|
||||
|
||||
/**
|
||||
* The list of properties currently registered in the configuration service.
|
||||
*/
|
||||
private Map properties = new Hashtable();
|
||||
|
||||
/**
|
||||
* Contains the properties that were initially loaded from the configuration
|
||||
* file or (if the properties have been modified and saved since initially
|
||||
* loaded) those that were last written to the file.We use the property so
|
||||
* that we could determine which properties are new and do not have a
|
||||
* corresponding node in the XMLDocument object.
|
||||
*/
|
||||
private Map fileExtractedProperties = new Hashtable();
|
||||
|
||||
/**
|
||||
* Sets the property with the specified name to the specified value. Calling
|
||||
* this method would first trigger a PropertyChangeEvent that will
|
||||
* be dispatched to all VetoableChangeListeners. In case no complaints
|
||||
* (PropertyVetoException) have been received, the property will be actually
|
||||
* changed and a PropertyChangeEvent will be dispatched.
|
||||
* <p>
|
||||
* @param propertyName String
|
||||
* @param property Object
|
||||
* @throws PropertyVetoException in case the changed has been refused by
|
||||
* at least one propertychange listener.
|
||||
*/
|
||||
public void setProperty(String propertyName, Object property)
|
||||
throws PropertyVetoException
|
||||
{
|
||||
setProperty(propertyName, property, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the property with the specified name to the specified. Calling
|
||||
* this method would first trigger a PropertyChangeEvent that will
|
||||
* be dispatched to all VetoableChangeListeners. In case no complaints
|
||||
* (PropertyVetoException) have been received, the property will be actually
|
||||
* changed and a PropertyChangeEvent will be dispatched. This method also
|
||||
* allows the caller to specify whether or not the specified property is a
|
||||
* system one.
|
||||
* <p>
|
||||
* @param propertyName the name of the property to change.
|
||||
* @param property the new value of the specified property.
|
||||
* @param isSystem specifies whether or not the property being is a System
|
||||
* property and should be resolved against the system
|
||||
* property set. If the property has previously been
|
||||
* specified as system then this value is inteernally forced
|
||||
* to true.
|
||||
* @throws PropertyVetoException in case the changed has been refused by
|
||||
* at least one propertychange listener.
|
||||
*/
|
||||
public void setProperty(String propertyName, Object property,
|
||||
boolean isSystem) throws PropertyVetoException
|
||||
{
|
||||
try{
|
||||
logger.logEntry();
|
||||
|
||||
Object oldValue = getProperty(propertyName);
|
||||
//first check whether the change is ok with everyone
|
||||
if (changeEventDispatcher.hasVetoableChangeListeners(propertyName))
|
||||
changeEventDispatcher.fireVetoableChange(
|
||||
propertyName, oldValue, property);
|
||||
|
||||
//no exception was thrown - lets change the property and fire a
|
||||
//change event
|
||||
|
||||
logger.trace(propertyName+"( oldValue="+oldValue
|
||||
+", newValue=" + property+".");
|
||||
|
||||
//once set system, a property remains system event if the user
|
||||
//specified sth else
|
||||
|
||||
if( isSystem(propertyName) )
|
||||
isSystem = true;
|
||||
|
||||
if (property == null){
|
||||
properties.remove(propertyName);
|
||||
|
||||
if(isSystem){
|
||||
//we can't remove or nullset a sys prop so let's "empty" it.
|
||||
System.setProperty(propertyName, "");
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(isSystem){
|
||||
//in case this is a system property, we must only store it
|
||||
//in the System property set and keep only a ref locally.
|
||||
System.setProperty(propertyName, property.toString());
|
||||
properties.put(propertyName,
|
||||
new PropertyReference(propertyName));
|
||||
}
|
||||
else{
|
||||
properties.put(propertyName, property);
|
||||
}
|
||||
}
|
||||
if (changeEventDispatcher.hasPropertyChangeListeners(propertyName))
|
||||
changeEventDispatcher.firePropertyChange(
|
||||
propertyName, oldValue, property);
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the property with the specified name or null if no
|
||||
* such property exists.
|
||||
* @param propertyName the name of the property that is being queried.
|
||||
* @return the value of the property with the specified name.
|
||||
*/
|
||||
public Object getProperty(String propertyName)
|
||||
{
|
||||
Object value = properties.get(propertyName);
|
||||
|
||||
//if this is a property reference make sure we return the referenced
|
||||
//value and not the reference itself
|
||||
if(value instanceof PropertyReference)
|
||||
return ((PropertyReference)value).getValue();
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PropertyChangeListener to the listener list.
|
||||
*
|
||||
* @param listener the PropertyChangeListener to be added
|
||||
*/
|
||||
public void addPropertyChangeListener(PropertyChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.addPropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a PropertyChangeListener from the listener list.
|
||||
*
|
||||
* @param listener the PropertyChangeListener to be removed
|
||||
*/
|
||||
public void removePropertyChangeListener(PropertyChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.removePropertyChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a PropertyChangeListener to the listener list for a specific
|
||||
* property.
|
||||
*
|
||||
* @param propertyName one of the property names listed above
|
||||
* @param listener the PropertyChangeListener to be added
|
||||
*/
|
||||
public void addPropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.
|
||||
addPropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a PropertyChangeListener from the listener list for a specific
|
||||
* property.
|
||||
*
|
||||
* @param propertyName a valid property name
|
||||
* @param listener the PropertyChangeListener to be removed
|
||||
*/
|
||||
public void removePropertyChangeListener(String propertyName,
|
||||
PropertyChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.
|
||||
removePropertyChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a VetoableChangeListener to the listener list.
|
||||
*
|
||||
* @param listener the VetoableChangeListener to be added
|
||||
*/
|
||||
public void addVetoableChangeListener(VetoableChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.addVetoableChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a VetoableChangeListener from the listener list.
|
||||
*
|
||||
* @param listener the VetoableChangeListener to be removed
|
||||
*/
|
||||
public void removeVetoableChangeListener(VetoableChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.removeVetoableChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a VetoableChangeListener to the listener list for a specific
|
||||
* property.
|
||||
*
|
||||
* @param propertyName one of the property names listed above
|
||||
* @param listener the VetoableChangeListener to be added
|
||||
*/
|
||||
public void addVetoableChangeListener(String propertyName,
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.addVetoableChangeListener(propertyName, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a VetoableChangeListener from the listener list for a specific
|
||||
* property.
|
||||
*
|
||||
* @param propertyName a valid property name
|
||||
* @param listener the VetoableChangeListener to be removed
|
||||
*/
|
||||
public void removeVetoableChangeListener(String propertyName,
|
||||
VetoableChangeListener listener)
|
||||
{
|
||||
changeEventDispatcher.removeVetoableChangeListener(propertyName,
|
||||
listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the configuration service impl and makes it load an initial
|
||||
* configuration from the conf file.
|
||||
*/
|
||||
void start()
|
||||
{
|
||||
try
|
||||
{
|
||||
reloadConfiguration();
|
||||
}
|
||||
catch (XMLException ex)
|
||||
{
|
||||
logger.error("Failed to parse the configuration file.", ex);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("Failed to load the configuration file", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadConfiguration()
|
||||
throws IOException, XMLException
|
||||
{
|
||||
properties = new Hashtable();
|
||||
fileExtractedProperties =
|
||||
loadConfiguration(getConfigurationFile());
|
||||
this.properties.putAll(fileExtractedProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the contents of the specified configuration file into the local
|
||||
* properties object.
|
||||
* @param file a reference to the configuration file to load.
|
||||
* @return a hashtable containing all properties extracted from the
|
||||
* specified file.
|
||||
*
|
||||
* @throws IOException if the specified file does not exist
|
||||
* @throws XMLException if there is a problem with the file syntax.
|
||||
*/
|
||||
Map loadConfiguration(File file)
|
||||
throws IOException, XMLException
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
DocumentBuilderFactory factory =
|
||||
DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
Map properties = new Hashtable();
|
||||
|
||||
propertiesDocument = builder.parse(file);
|
||||
|
||||
Node root = propertiesDocument.getFirstChild();
|
||||
|
||||
Node currentNode = null;
|
||||
NodeList children = root.getChildNodes();
|
||||
for(int i = 0; i < children.getLength(); i++)
|
||||
{
|
||||
currentNode = children.item(i);
|
||||
|
||||
if(currentNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
StringBuffer propertyNameBuff = new StringBuffer();
|
||||
propertyNameBuff.append(currentNode.getNodeName());
|
||||
loadNode(currentNode, propertyNameBuff, properties);
|
||||
}
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
catch(SAXException ex)
|
||||
{
|
||||
logger.error("Error parsing configuration file", ex);
|
||||
throw new XMLException(ex.getMessage(), ex);
|
||||
}
|
||||
catch(ParserConfigurationException ex)
|
||||
{
|
||||
//it is not highly probable that this might happen - so lets just
|
||||
//log it.
|
||||
logger.error("Error finding configuration for default parsers", ex);
|
||||
return new Hashtable();
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
}
|
||||
|
||||
public void storeConfiguration()
|
||||
throws IOException
|
||||
{
|
||||
storeConfiguration(getConfigurationFile());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores local properties in the specified configuration file.
|
||||
* @param file a reference to the configuration file where properties should
|
||||
* be stored.
|
||||
* @throws IOException if there was a problem writing to the specified file.
|
||||
*/
|
||||
private void storeConfiguration(File file)
|
||||
throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
DocumentBuilderFactory factory =
|
||||
DocumentBuilderFactory.newInstance();
|
||||
|
||||
//resolve the properties that were initially in the file - back to
|
||||
//the document.
|
||||
|
||||
Node root = propertiesDocument.getFirstChild();
|
||||
|
||||
Node currentNode = null;
|
||||
NodeList children = root.getChildNodes();
|
||||
for(int i = 0; i < children.getLength(); i++)
|
||||
{
|
||||
currentNode = children.item(i);
|
||||
|
||||
if(currentNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
StringBuffer propertyNameBuff = new StringBuffer();
|
||||
propertyNameBuff.append(currentNode.getNodeName());
|
||||
updateNode(currentNode, propertyNameBuff, properties);
|
||||
}
|
||||
}
|
||||
|
||||
//create in the document the properties that were added by other
|
||||
//bundles after the initial property load.
|
||||
|
||||
Map newlyAddedProperties = cloneProperties();
|
||||
|
||||
//remove those that were originally there;
|
||||
Iterator propNames = fileExtractedProperties.keySet().iterator();
|
||||
while(propNames.hasNext())
|
||||
newlyAddedProperties.remove(propNames.next());
|
||||
|
||||
this.processNewProperties(propertiesDocument,
|
||||
newlyAddedProperties);
|
||||
|
||||
|
||||
//write the file.
|
||||
XMLConfUtils.writeXML(propertiesDocument, getConfigurationFile());
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the contents of the specified node and its children into the local
|
||||
* properties. Any nodes marked as "system" will also be resolved in the
|
||||
* system properties.
|
||||
* @param node the root node that we shold load together with its children
|
||||
* @param propertyNameBuff a StringBuffer containing the prefix describing
|
||||
* the route to the specified node including its one name
|
||||
* @param properties the dictionary object where all properties extracted
|
||||
* from this node and its children should be recorded.
|
||||
*/
|
||||
private void loadNode(Node node,
|
||||
StringBuffer propertyNameBuff,
|
||||
Map properties)
|
||||
{
|
||||
Node currentNode = null;
|
||||
NodeList children = node.getChildNodes();
|
||||
for(int i = 0; i < children.getLength(); i++)
|
||||
{
|
||||
currentNode = children.item(i);
|
||||
|
||||
if(currentNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
StringBuffer newPropBuff =
|
||||
new StringBuffer(propertyNameBuff
|
||||
+ "." +currentNode.getNodeName());
|
||||
String value = XMLConfUtils.getAttribute(
|
||||
currentNode, ATTRIBUTE_VALUE);
|
||||
|
||||
String propertyType =
|
||||
XMLConfUtils.getAttribute(currentNode, SYSTEM_ATTRIBUTE_NAME);
|
||||
|
||||
// the value attr is present we must handle the desired property
|
||||
if(value != null)
|
||||
{
|
||||
|
||||
//if the property is marked as "system", we should resolve
|
||||
//it against the system properties and only store a
|
||||
//reference locally. this is normally done for properties
|
||||
//that are supposed to configure underlying libraries.
|
||||
if(propertyType != null
|
||||
&& propertyType.equals(SYSTEM_ATTRIBUTE_TRUE))
|
||||
{
|
||||
properties.put(
|
||||
newPropBuff.toString(),
|
||||
new PropertyReference(newPropBuff.toString()));
|
||||
System.setProperty(newPropBuff.toString(), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
properties.put(newPropBuff.toString(), value);
|
||||
}
|
||||
}
|
||||
|
||||
//load child nodes
|
||||
loadNode(currentNode, newPropBuff, properties);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the value of the specified node and its children to reflect those
|
||||
* in the properties file. Nodes marked as "system" will be updated from
|
||||
* the specified properties object and not from the system properties since
|
||||
* if any intentional change (through a configuration form) has occurred
|
||||
* it will have been made there.
|
||||
*
|
||||
* @param node the root node that we shold update together with its children
|
||||
* @param propertyNameBuff a StringBuffer containing the prefix describing
|
||||
* the dot separated route to the specified node including its one name
|
||||
* @param properties the dictionary object where the up to date values of
|
||||
* the node should be queried.
|
||||
*/
|
||||
private void updateNode(Node node,
|
||||
StringBuffer propertyNameBuff,
|
||||
Map properties)
|
||||
{
|
||||
Node currentNode = null;
|
||||
NodeList children = node.getChildNodes();
|
||||
for(int i = 0; i < children.getLength(); i++)
|
||||
{
|
||||
currentNode = children.item(i);
|
||||
|
||||
if(currentNode.getNodeType() == Node.ELEMENT_NODE)
|
||||
{
|
||||
StringBuffer newPropBuff =
|
||||
new StringBuffer(propertyNameBuff
|
||||
+ "." +currentNode.getNodeName());
|
||||
|
||||
Attr attr =
|
||||
((Element)currentNode).getAttributeNode(ATTRIBUTE_VALUE);
|
||||
|
||||
if(attr != null)
|
||||
{
|
||||
//update the corresponding node
|
||||
Object value = properties.get(newPropBuff.toString());
|
||||
boolean isSystem = value instanceof PropertyReference;
|
||||
String prop = isSystem
|
||||
?((PropertyReference)value).getValue().toString()
|
||||
:value.toString();
|
||||
|
||||
attr.setNodeValue(prop);
|
||||
|
||||
//in case the property has changed to system since the last
|
||||
//load - update the conf file accordingly.
|
||||
if(isSystem)
|
||||
((Element)currentNode).setAttribute(
|
||||
SYSTEM_ATTRIBUTE_NAME, SYSTEM_ATTRIBUTE_TRUE);
|
||||
else
|
||||
((Element)currentNode).removeAttribute(
|
||||
SYSTEM_ATTRIBUTE_NAME);
|
||||
|
||||
}
|
||||
|
||||
//update child nodes
|
||||
updateNode(currentNode, newPropBuff, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the configuration file that the service should
|
||||
* load. The method would try to load a file with the name
|
||||
* sip-communicator.xml unless a different one is specified in the system
|
||||
* property net.java.sip.communicator.PROPERTIES_FILE_NAME . The method
|
||||
* would first try to load the file from the current directory if it exists
|
||||
* this is not the case a load would be attempted from the
|
||||
* $HOME/.sip-communicator directory. In case it was not found there either
|
||||
* we'll look for it in all locations currently present in the $CLASSPATH.
|
||||
* In case we find it in there we will copy it to the
|
||||
* $HOME/.sip-communicator directory in case it was in a jar archive and
|
||||
* return the reference to the newly created file. In case the file is
|
||||
* to be found noweher - a new empty file in the user home directory and
|
||||
* returns a link to that one.
|
||||
*
|
||||
*
|
||||
* @return the configuration the sip-
|
||||
*/
|
||||
File getConfigurationFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
//see whether we have a user specified name for the conf file
|
||||
String pFileName = getSystemProperty(
|
||||
FILE_NAME_PROPERTY);
|
||||
if (pFileName == null)
|
||||
{
|
||||
pFileName = "sip-communicator.xml";
|
||||
}
|
||||
|
||||
// try to open the file in current directory
|
||||
File configFileInCurrentDir = new File(pFileName);
|
||||
if (configFileInCurrentDir.exists())
|
||||
{
|
||||
logger.debug("Using config file in current dir: "
|
||||
+ configFileInCurrentDir.getCanonicalPath());
|
||||
return configFileInCurrentDir;
|
||||
}
|
||||
|
||||
// we didn't find it in ".", try the user.home directory
|
||||
File configDir = new File(getSystemProperty("user.home") +
|
||||
File.separator +
|
||||
".sip-communicator");
|
||||
|
||||
File configFileInUserHomeDir =
|
||||
new File(configDir, pFileName);
|
||||
|
||||
if (configFileInUserHomeDir.exists())
|
||||
{
|
||||
logger.debug("Using config file in $HOME/.sip-communicator: "
|
||||
+ configFileInCurrentDir.getCanonicalPath());
|
||||
return configFileInUserHomeDir;
|
||||
}
|
||||
|
||||
// If we are in a jar - copy config file from jar to user home.
|
||||
logger.trace("Copying config file.");
|
||||
|
||||
configDir.mkdirs();
|
||||
InputStream in = getClass().getClassLoader().
|
||||
getResourceAsStream(pFileName);
|
||||
|
||||
//Return an empty file if there wasn't any in the jar
|
||||
//null check report from John J. Barton - IBM
|
||||
if (in == null)
|
||||
{
|
||||
configFileInUserHomeDir.createNewFile();
|
||||
logger.debug("Created an empty file in $HOME: "
|
||||
+ configFileInCurrentDir.getCanonicalPath());
|
||||
return configFileInUserHomeDir;
|
||||
}
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(in));
|
||||
|
||||
PrintWriter writer = new PrintWriter(new FileWriter(
|
||||
configFileInUserHomeDir));
|
||||
|
||||
String line = null;
|
||||
logger.debug("Copying properties file:");
|
||||
while ( (line = reader.readLine()) != null)
|
||||
{
|
||||
writer.println(line);
|
||||
logger.debug(line);
|
||||
}
|
||||
writer.flush();
|
||||
return configFileInUserHomeDir;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("Error creating config file", ex);
|
||||
return null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new entries in the xml <code>doc</code> for every element in the
|
||||
* <code>newProperties</code> table.
|
||||
*
|
||||
* @param doc the XML <code>Document</code> where the new entries should be
|
||||
* created
|
||||
* @param newProperties the table containing the properties that are to be
|
||||
* in troduced in the document.
|
||||
*/
|
||||
private void processNewProperties(Document doc,
|
||||
Map newProperties)
|
||||
{
|
||||
Iterator propNames = newProperties.keySet().iterator();
|
||||
while(propNames.hasNext())
|
||||
{
|
||||
String key = (String)propNames.next();
|
||||
Object value = newProperties.get(key);
|
||||
boolean isSystem = value instanceof PropertyReference;
|
||||
value = isSystem
|
||||
?((PropertyReference)value).getValue()
|
||||
:value;
|
||||
processNewProperty(doc, key, value.toString(), isSystem);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an entry in the xml <code>doc</code> for the specified key value
|
||||
* pair.
|
||||
* @param doc the XML <code>document</code> to update.
|
||||
* @param key the value of the <code>name</code> attribute for the new entry
|
||||
* @param value the value of the <code>value</code> attribue for the new
|
||||
* @param isSystem specifies whether this is a system property (system
|
||||
* attribute will be set to true).
|
||||
* entry.
|
||||
*/
|
||||
private void processNewProperty(Document doc,
|
||||
String key,
|
||||
String value,
|
||||
boolean isSystem)
|
||||
{
|
||||
StringTokenizer tokenizer = new StringTokenizer(key, ".");
|
||||
String[] toks = new String[tokenizer.countTokens()];
|
||||
int i = 0;
|
||||
while(tokenizer.hasMoreTokens())
|
||||
toks[i++] = tokenizer.nextToken();
|
||||
|
||||
String[] chain = new String[toks.length - 1];
|
||||
for (int j = 0; j < chain.length; j++)
|
||||
{
|
||||
chain[j] = toks[j];
|
||||
}
|
||||
|
||||
String nodeName = toks[toks.length - 1];
|
||||
|
||||
Element parent = XMLConfUtils.createLastPathComponent(doc, chain);
|
||||
Element newNode = XMLConfUtils.findChild(parent, nodeName);
|
||||
if (newNode == null)
|
||||
{
|
||||
newNode = doc.createElement(nodeName);
|
||||
parent.appendChild(newNode);
|
||||
}
|
||||
newNode.setAttribute("value", value);
|
||||
|
||||
if(isSystem)
|
||||
newNode.setAttribute(SYSTEM_ATTRIBUTE_NAME, SYSTEM_ATTRIBUTE_TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value of the specified java system property. In case the
|
||||
* value was a zero length String or one that only contained whitespaces,
|
||||
* null is returned. This method is for internal use only. Users of the
|
||||
* configuration service are to use the getProperty() or getString() methods
|
||||
* which would automatically determine whether a property is system or not.
|
||||
* @param propertyName the name of the property whose value we need.
|
||||
* @return the value of the property with name propertyName or null if
|
||||
* the value had length 0 or only contained spaces tabs or new lines.
|
||||
*/
|
||||
private static String getSystemProperty(String propertyName)
|
||||
{
|
||||
String retval = System.getProperty(propertyName);
|
||||
if (retval == null){
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (retval.trim().length() == 0){
|
||||
return null;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String value of the specified property (minus all
|
||||
* encompasssing whitespaces)and null in case no property value was mapped
|
||||
* against the specified propertyName, or in case the returned property
|
||||
* string had zero length or contained whitespaces only.
|
||||
*
|
||||
* @param propertyName the name of the property that is being queried.
|
||||
* @return the result of calling the property's toString method and null in
|
||||
* case there was no vlaue mapped against the specified
|
||||
* <code>propertyName</code>, or the returned string had zero length or
|
||||
* contained whitespaces only.
|
||||
*/
|
||||
public String getString(String propertyName)
|
||||
{
|
||||
Object propValue = getProperty(propertyName);
|
||||
if (propValue == null)
|
||||
return null;
|
||||
|
||||
String propStrValue = propValue.toString().trim();
|
||||
|
||||
return propStrValue.length() > 0
|
||||
? propStrValue
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* We use property references when we'd like to store system properties.
|
||||
* Simply storing System properties in our properties Map would not be
|
||||
* enough since it will lead to mismatching values for the same property in
|
||||
* the System property set and in our local set of properties. Storing them
|
||||
* only in the System property set OTOH is a bit clumsy since it obliges
|
||||
* bundles to use to different configuration property sources. For that
|
||||
* reason, every time we get handed a property labeled as System, in stead
|
||||
* of storing its actual value in the local property set we store a
|
||||
* PropertyReference instance that will retrive it from the system
|
||||
* properties when necessary.
|
||||
*/
|
||||
private class PropertyReference
|
||||
{
|
||||
private String propertyName = null;
|
||||
|
||||
PropertyReference(String propertyName)
|
||||
{
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the actual value of the property as recorded in the System
|
||||
* properties.
|
||||
* @return the valued of the property as recorded in the System props.
|
||||
*/
|
||||
public Object getValue()
|
||||
{
|
||||
return System.getProperty(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the Map containing all configuration properties
|
||||
* @return a Map clone of the current configuration property set.
|
||||
*/
|
||||
private Map cloneProperties()
|
||||
{
|
||||
//at the time I'm writing this method we're implementing the
|
||||
//configuraiton service through the use of a hashtable. this may very
|
||||
//well change one day so let's not be overy assumptious (can you
|
||||
//actually say that?)
|
||||
if(properties instanceof Hashtable)
|
||||
return (Map)((Hashtable)properties).clone();
|
||||
if(properties instanceof HashMap)
|
||||
return (Map)((HashMap)properties).clone();
|
||||
if(properties instanceof TreeMap)
|
||||
return (Map)((TreeMap)properties).clone();
|
||||
|
||||
//well you can't say that I didn't try!!!
|
||||
|
||||
return new Hashtable(properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the property with the specified
|
||||
* <code>propertyName</code> has been previously declared as System
|
||||
*
|
||||
* @param propertyName the name of the property to verify
|
||||
* @return true if someone at some point specified that property to be
|
||||
* system. (This could have been either through a call to
|
||||
* setProperty(string, true)) or by setting the system attribute in the
|
||||
* xml conf file to true.
|
||||
*/
|
||||
private boolean isSystem(String propertyName)
|
||||
{
|
||||
return properties.containsKey(propertyName)
|
||||
&& properties.get(propertyName) instanceof PropertyReference;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
Bundle-Activator: net.java.sip.communicator.impl.configuration.Activator
|
||||
Bundle-Name: Configuration Service Implementation
|
||||
Bundle-Description: A bundle that offers configuration utilities
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Import-Package: org.osgi.framework,
|
||||
org.apache.xml.serializer,
|
||||
org.xml.sax,
|
||||
org.w3c.dom,
|
||||
javax.xml.transform,
|
||||
javax.xml.transform.dom,
|
||||
javax.xml.transform.stream,
|
||||
javax.xml.parsers,
|
||||
net.java.sip.communicator.util,
|
||||
net.java.sip.communicator.util.xml,
|
||||
Export-Package: net.java.sip.communicator.service.configuration,
|
||||
net.java.sip.communicator.service.configuration.event,
|
||||
net.java.sip.communicator.impl.configuration.xml,
|
||||
@ -0,0 +1,7 @@
|
||||
Bundle-Activator: net.java.sip.communicator.impl.configuration.Activator
|
||||
Export-Package: net.java.sip.communicator.service.configuration;net.java.sip.communicator.service.configuration.event;
|
||||
Import-Package: net.java.sip.communicator.service.configuration;junit;junit.framework;junit.swingui;junit.textui;junit.awtui;junit.extensions;org.osgi.framework
|
||||
Bundle-Name: Configuration Service Implementation
|
||||
Bundle-Description: A bundle that offers configuration utilities
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
|
||||
*
|
||||
* Distributable under LGPL license.
|
||||
* See terms of license at gnu.org.
|
||||
*/
|
||||
package net.java.sip.communicator.impl.configuration.xml;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
import net.java.sip.communicator.util.xml.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Common XML Tasks.
|
||||
*
|
||||
* @author Damian Minkov
|
||||
* @author Emil Ivov
|
||||
*/
|
||||
public class XMLConfUtils extends XMLUtils
|
||||
{
|
||||
private static Logger logger = Logger.getLogger(XMLConfUtils.class);
|
||||
|
||||
/**
|
||||
* Returns the element which is at the end of the specified
|
||||
* String chain. <great...grandparent>...<grandparent>.<parent>.<child>
|
||||
* @param parent the xml element that is the parent of the root of this
|
||||
* chain.
|
||||
* @param chain a String array containing the names of all the child's
|
||||
* parent nodes.
|
||||
* @return the node represented by the specified chain
|
||||
*/
|
||||
public static Element getChildElementByChain(Element parent,
|
||||
String[] chain,
|
||||
boolean create)
|
||||
{
|
||||
if(chain == null)
|
||||
return null;
|
||||
Element e = parent;
|
||||
for(int i=0; i<chain.length; i++)
|
||||
{
|
||||
if(e == null)
|
||||
return null;
|
||||
e = findChild(e, chain[i]);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates (only if necessary) and returns the element which is at the end
|
||||
* of the specified path.
|
||||
* @param doc the target document where the specified path should be created
|
||||
* @param path a dot separated string indicating the path to be created
|
||||
* @return the component at the end of the newly created path.
|
||||
*/
|
||||
public static Element createLastPathComponent(Document doc, String[] path)
|
||||
{
|
||||
Element parent = (Element)doc.getFirstChild();
|
||||
if( path == null
|
||||
|| parent == null
|
||||
|| doc == null)
|
||||
throw new IllegalArgumentException(
|
||||
"Document parent and path must not be null");
|
||||
|
||||
Element e = parent;
|
||||
for(int i=0; i < path.length; i++)
|
||||
{
|
||||
Element newEl = findChild(e, path[i]);
|
||||
if(newEl == null)
|
||||
{
|
||||
newEl = doc.createElement(path[i]);
|
||||
e.appendChild(newEl);
|
||||
}
|
||||
e = newEl;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
package net.java.sip.communicator.impl.gui;
|
||||
|
||||
import net.java.sip.communicator.service.gui.UIService;
|
||||
import net.java.sip.communicator.util.Logger;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
||||
public class Activator implements BundleActivator
|
||||
{
|
||||
|
||||
private Logger logger = Logger.getLogger(Activator.class.getName());
|
||||
|
||||
private UIService uiService = null;
|
||||
|
||||
public void start(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
logger.logEntry();
|
||||
|
||||
//Create the ui service
|
||||
this.uiService =
|
||||
new UIServiceImpl();
|
||||
|
||||
logger.info("UI Service...[ STARTED ]");
|
||||
|
||||
bundleContext.registerService(
|
||||
UIService.class.getName(), this.uiService, null);
|
||||
|
||||
logger.info("UI Service ...[REGISTERED]");
|
||||
}
|
||||
finally
|
||||
{
|
||||
logger.logExit();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(BundleContext bundleContext) throws Exception
|
||||
{
|
||||
logger.info("UI Service ...[STOPED]");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package net.java.sip.communicator.impl.gui;
|
||||
|
||||
import net.java.sip.communicator.service.gui.UIService;
|
||||
import net.java.sip.communicator.service.protocol.Call;
|
||||
import net.java.sip.communicator.service.protocol.ProtocolProviderService;
|
||||
|
||||
public class UIServiceImpl implements UIService {
|
||||
|
||||
|
||||
public void registerProvider(ProtocolProviderService provider) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void setVisible(boolean visible) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public Call[] getActiveCalls() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getUiLibName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public String[] getSupportedUiLibNames() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addMenuItem(String parent, Object menuItem)
|
||||
throws ClassCastException, IllegalArgumentException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void addComponent(Object component, String constraint)
|
||||
throws ClassCastException, IllegalArgumentException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void addUserActionListener() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void requestAuthentication(String realm, String userName,
|
||||
char[] password) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public String getAuthenticationUserName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
Bundle-Activator: net.java.sip.communicator.impl.gui.Activator
|
||||
Bundle-Name: Resources Management Service Provider
|
||||
Bundle-Description: A bundle that implements the resource management package.
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Export-Package: net.java.sip.communicator.gui,
|
||||
@ -0,0 +1,19 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JList;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The call list.
|
||||
* TODO: to be removed.
|
||||
*/
|
||||
|
||||
public class CallList extends JList {
|
||||
|
||||
public CallList(Vector data){
|
||||
super(data);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Image;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.customcontrols.SIPCommButton;
|
||||
|
||||
public class CallPanel extends JPanel{
|
||||
|
||||
private Image callButtonIcon = LookAndFeelConstants.CALL_BUTTON_ICON;
|
||||
private Image hangupButtonIcon = LookAndFeelConstants.HANG_UP_BUTTON_ICON;
|
||||
private Image callButtonBG = LookAndFeelConstants.CALL_BUTTON_BG;
|
||||
private Image callButtonRolloverBG = LookAndFeelConstants.CALL_ROLLOVER_BUTTON_BG;
|
||||
private Image hangupButtonBG = LookAndFeelConstants.HANGUP_BUTTON_BG;
|
||||
private Image hangupButtonRolloverBG = LookAndFeelConstants.HANGUP_ROLLOVER_BUTTON_BG;
|
||||
|
||||
private JComboBox phoneNumberCombo = new JComboBox();
|
||||
private JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
private SIPCommButton callButton;
|
||||
private SIPCommButton hangupButton;
|
||||
|
||||
public CallPanel(){
|
||||
|
||||
super(new BorderLayout());
|
||||
|
||||
callButton = new SIPCommButton(callButtonBG,
|
||||
callButtonRolloverBG,
|
||||
callButtonIcon);
|
||||
hangupButton = new SIPCommButton(hangupButtonBG,
|
||||
hangupButtonRolloverBG,
|
||||
hangupButtonIcon);
|
||||
|
||||
this.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 5));
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.phoneNumberCombo.setEditable(true);
|
||||
|
||||
this.add(phoneNumberCombo, BorderLayout.NORTH);
|
||||
|
||||
this.buttonsPanel.add(callButton);
|
||||
this.buttonsPanel.add(hangupButton);
|
||||
|
||||
this.add(buttonsPanel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,96 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import javax.swing.plaf.metal.MetalTheme;
|
||||
|
||||
import com.l2fprod.gui.plaf.skin.Skin;
|
||||
import com.l2fprod.gui.plaf.skin.SkinLookAndFeel;
|
||||
import com.l2fprod.util.OS;
|
||||
|
||||
//import examples.demo;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* Starts the GUI application using the SkinLookAndFeel of l2fprod.
|
||||
*/
|
||||
public class CommunicatorMain {
|
||||
|
||||
public static void main(String[] args){
|
||||
|
||||
try {
|
||||
//the theme could be passed as a parameter
|
||||
if (args.length > 0) {
|
||||
String themepack = args[0];
|
||||
if (themepack.endsWith(".xml")) {
|
||||
SkinLookAndFeel.setSkin(
|
||||
SkinLookAndFeel.loadThemePackDefinition(new File(args[0]).toURL()));
|
||||
UIManager.setLookAndFeel("com.l2fprod.gui.plaf.skin.SkinLookAndFeel");
|
||||
} else if (themepack.startsWith("class:")) {
|
||||
String classname = themepack.substring("class:".length());
|
||||
SkinLookAndFeel.setSkin((Skin)Class.forName(classname).newInstance());
|
||||
UIManager.setLookAndFeel("com.l2fprod.gui.plaf.skin.SkinLookAndFeel");
|
||||
} else if (themepack.startsWith("theme:")) {
|
||||
String classname = themepack.substring("theme:".length());
|
||||
MetalTheme theme = (MetalTheme)Class.forName(classname).newInstance();
|
||||
MetalLookAndFeel metal = new MetalLookAndFeel();
|
||||
MetalLookAndFeel.setCurrentTheme(theme);
|
||||
UIManager.setLookAndFeel(metal);
|
||||
} else {
|
||||
SkinLookAndFeel.setSkin(SkinLookAndFeel.loadThemePack(args[0]));
|
||||
UIManager.setLookAndFeel("com.l2fprod.gui.plaf.skin.SkinLookAndFeel");
|
||||
}
|
||||
}
|
||||
//the default theme is set if no theme is specified
|
||||
else{
|
||||
SkinLookAndFeel.setSkin(
|
||||
SkinLookAndFeel.loadThemePackDefinition(new File("src/net/java/sip/communicator/impl/gui/themepacks/aquathemepack/skinlf-themepack.xml").toURL()));
|
||||
UIManager.setLookAndFeel("com.l2fprod.gui.plaf.skin.SkinLookAndFeel");
|
||||
}
|
||||
|
||||
//Decorates the frames and dialogs if we are running with jdk1.4 +
|
||||
/*
|
||||
if (OS.isOneDotFourOrMore()) {
|
||||
java.lang.reflect.Method method = JFrame.class.getMethod(
|
||||
"setDefaultLookAndFeelDecorated",
|
||||
new Class[] { boolean.class });
|
||||
method.invoke(null, new Object[] { Boolean.TRUE });
|
||||
|
||||
method = JDialog.class.getMethod(
|
||||
"setDefaultLookAndFeelDecorated",
|
||||
new Class[] { boolean.class });
|
||||
method.invoke(null, new Object[] { Boolean.TRUE });
|
||||
}*/
|
||||
|
||||
} catch (Exception e) { }
|
||||
|
||||
//Image frameIcon =
|
||||
//new ImageIcon(demo.class.getResource("windowicon.gif")).getImage();
|
||||
// so option pane as same icon as us
|
||||
//JOptionPane.getRootFrame().setIconImage(frameIcon);
|
||||
|
||||
//TODO: To be removed when the contact list service is ready
|
||||
ContactList clist = new ContactList();
|
||||
|
||||
clist.addContact(new ContactItem("user1"));
|
||||
clist.addContact(new ContactItem("user2"));
|
||||
clist.addContact(new ContactItem("user3"));
|
||||
|
||||
User user = new User();
|
||||
|
||||
user.setProtocols(new String[]{"ICQ", "MSN"});
|
||||
|
||||
MainFrame mainFrame = new MainFrame(clist, user);
|
||||
//mainFrame.setIconImage(frameIcon);
|
||||
|
||||
mainFrame.setTitle("SIP Communicator");
|
||||
mainFrame.pack();
|
||||
|
||||
mainFrame.setVisible(true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.Image;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The contact.
|
||||
* TODO: To be removed when the contact list service is ready.
|
||||
*/
|
||||
|
||||
public class ContactItem {
|
||||
|
||||
private String nickname;
|
||||
private Image photo;
|
||||
private String[] protocolList;
|
||||
private String status;
|
||||
|
||||
public ContactItem(String nickname){
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickName(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public Image getPhoto() {
|
||||
return photo;
|
||||
}
|
||||
|
||||
public void setPhoto(Image photo) {
|
||||
this.photo = photo;
|
||||
}
|
||||
|
||||
public String[] getProtocolList() {
|
||||
return protocolList;
|
||||
}
|
||||
|
||||
public void setProtocolList(String[] protocolList) {
|
||||
this.protocolList = protocolList;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The contact list.
|
||||
* TODO: to be removed when the contact list service is ready.
|
||||
*/
|
||||
|
||||
public class ContactList {
|
||||
|
||||
private Vector contacts = new Vector();
|
||||
|
||||
public Vector getAllContacts(){
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void addContact(ContactItem contactItem){
|
||||
contacts.add(contactItem);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,81 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The ContactListPanel contains the contact list.
|
||||
*/
|
||||
public class ContactListPanel extends JScrollPane{
|
||||
|
||||
private ContactList clist;
|
||||
private JPanel mainPanel = new JPanel();
|
||||
private JPanel contactsPanel = new JPanel();
|
||||
|
||||
public ContactListPanel(ContactList clist){
|
||||
|
||||
this.mainPanel.setLayout(new BorderLayout());
|
||||
this.contactsPanel.setLayout(new BoxLayout(this.contactsPanel, BoxLayout.Y_AXIS));
|
||||
|
||||
this.clist = clist;
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
|
||||
for (int i = 0; i < this.clist.getAllContacts().size(); i ++){
|
||||
|
||||
ContactPanel cpanel = new ContactPanel((ContactItem)this.clist.getAllContacts().get(i));
|
||||
cpanel.setPreferredSize(new Dimension(LookAndFeelConstants.CONTACTPANEL_WIDTH, LookAndFeelConstants.CONTACTPANEL_HEIGHT));
|
||||
|
||||
cpanel.addMouseListener(new MouseAdapter(){
|
||||
public void mouseEntered(MouseEvent e){
|
||||
ContactPanel cpanel = (ContactPanel)e.getSource();
|
||||
|
||||
cpanel.setMouseOver(true);
|
||||
cpanel.repaint();
|
||||
}
|
||||
|
||||
public void mouseExited(MouseEvent e){
|
||||
ContactPanel cpanel = (ContactPanel)e.getSource();
|
||||
|
||||
cpanel.setMouseOver(false);
|
||||
cpanel.repaint();
|
||||
}
|
||||
|
||||
public void mouseClicked(MouseEvent e){
|
||||
ContactPanel cpanel = (ContactPanel)e.getSource();
|
||||
|
||||
cpanel.setSelected(true);
|
||||
refreshContactsStatus(cpanel);
|
||||
}
|
||||
});
|
||||
|
||||
this.contactsPanel.add(cpanel);
|
||||
}
|
||||
|
||||
this.mainPanel.add(contactsPanel, BorderLayout.NORTH);
|
||||
this.getViewport().add(mainPanel);
|
||||
}
|
||||
|
||||
public void refreshContactsStatus(ContactPanel cpanelSelected){
|
||||
|
||||
for (int i = 0; i < this.contactsPanel.getComponentCount(); i ++){
|
||||
ContactPanel cpanel = (ContactPanel)this.contactsPanel.getComponent(i);
|
||||
|
||||
if(!cpanel.equals(cpanelSelected)){
|
||||
cpanel.setSelected(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import javax.swing.JTree;
|
||||
|
||||
public class ContactListTree extends JTree {
|
||||
|
||||
}
|
||||
@ -0,0 +1,138 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The ContactPanel contains the contact item.
|
||||
*/
|
||||
|
||||
public class ContactPanel extends JPanel {
|
||||
|
||||
private ContactItem contactItem;
|
||||
|
||||
private boolean isMouseOver = false;
|
||||
private boolean isSelected = false;
|
||||
|
||||
private JLabel nicknameLabel = new JLabel();
|
||||
|
||||
public ContactPanel(ContactItem contactItem){
|
||||
super(new BorderLayout());
|
||||
|
||||
this.contactItem = contactItem;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
|
||||
nicknameLabel.setFont(this.getFont().deriveFont(Font.BOLD));
|
||||
|
||||
this.setUserData();
|
||||
|
||||
this.add(nicknameLabel, BorderLayout.WEST);
|
||||
|
||||
}
|
||||
|
||||
public void setUserData(){
|
||||
nicknameLabel.setText(this.contactItem.getNickName());
|
||||
}
|
||||
|
||||
public void paintComponent(Graphics g){
|
||||
super.paintComponent(g);
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
|
||||
if(this.isSelected()){
|
||||
GradientPaint p = new GradientPaint(this.getWidth()/2,
|
||||
0,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_START_COLOR,
|
||||
this.getWidth()/2,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_END_COLOR);
|
||||
|
||||
GradientPaint p1 = new GradientPaint( this.getWidth()/2,
|
||||
this.getHeight() - LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_END_COLOR,
|
||||
this.getWidth()/2,
|
||||
this.getHeight(),
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_START_COLOR);
|
||||
|
||||
g2.setPaint(p);
|
||||
g2.fillRect(0, 0, this.getWidth(), LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE);
|
||||
|
||||
g2.setColor(LookAndFeelConstants.CONTACTPANEL_SELECTED_END_COLOR);
|
||||
g2.fillRect(0,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE,
|
||||
this.getWidth(),
|
||||
this.getHeight() - LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE);
|
||||
|
||||
g2.setPaint(p1);
|
||||
g2.fillRect(0, this.getHeight() - LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE, this.getWidth(), this.getHeight() - 1);
|
||||
}
|
||||
else if(this.isMouseOver()){
|
||||
GradientPaint p = new GradientPaint(this.getWidth()/2,
|
||||
0,
|
||||
LookAndFeelConstants.CONTACTPANEL_MOVER_START_COLOR,
|
||||
this.getWidth()/2,
|
||||
LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE,
|
||||
LookAndFeelConstants.CONTACTPANEL_MOVER_END_COLOR);
|
||||
|
||||
GradientPaint p1 = new GradientPaint( this.getWidth()/2,
|
||||
this.getHeight() - LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE,
|
||||
LookAndFeelConstants.CONTACTPANEL_MOVER_END_COLOR,
|
||||
this.getWidth()/2,
|
||||
this.getHeight(),
|
||||
LookAndFeelConstants.CONTACTPANEL_MOVER_START_COLOR);
|
||||
|
||||
g2.setPaint(p);
|
||||
g2.fillRect(0, 0, this.getWidth(), LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE);
|
||||
|
||||
g2.setColor(LookAndFeelConstants.CONTACTPANEL_MOVER_END_COLOR);
|
||||
g2.fillRect(0,
|
||||
LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE,
|
||||
this.getWidth(),
|
||||
this.getHeight() - LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE);
|
||||
|
||||
g2.setPaint(p1);
|
||||
g2.fillRect(0, this.getHeight() - LookAndFeelConstants.CONTACTPANEL_GRADIENT_SIZE - 1, this.getWidth(), this.getHeight() - 1);
|
||||
}
|
||||
|
||||
g2.setColor(LookAndFeelConstants.CONTACTPANEL_LINES_COLOR);
|
||||
g2.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1);
|
||||
}
|
||||
|
||||
public boolean isMouseOver() {
|
||||
return isMouseOver;
|
||||
}
|
||||
|
||||
public void setMouseOver(boolean isMouseOver) {
|
||||
this.isMouseOver = isMouseOver;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean isSelected) {
|
||||
if(this.isSelected != isSelected) {
|
||||
this.isSelected = isSelected;
|
||||
/*if(isSelected) {
|
||||
this.setSize(new Dimension(this.getWidth(), LookAndFeelConstants.CONTACTPANEL_SELECTED_HEIGHT));
|
||||
} else {
|
||||
this.setSize(new Dimension(this.getWidth(), LookAndFeelConstants.CONTACTPANEL_HEIGHT));
|
||||
}*/
|
||||
this.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The DialPanel contains the dial buttons.
|
||||
*/
|
||||
|
||||
public class DialPanel extends JPanel {
|
||||
private Font buttonTextFont = new Font("Verdana", Font.BOLD, 12);
|
||||
|
||||
private JButton oneButton = new JButton("1");
|
||||
private JButton twoButton = new JButton("2");
|
||||
private JButton threeButton = new JButton("3");
|
||||
private JButton fourButton = new JButton("4");
|
||||
private JButton fiveButton = new JButton("5");
|
||||
private JButton sixButton = new JButton("6");
|
||||
private JButton sevenButton = new JButton("7");
|
||||
private JButton eightButton = new JButton("8");
|
||||
private JButton nineButton = new JButton("9");
|
||||
private JButton starButton = new JButton("*");
|
||||
private JButton zeroButton = new JButton("0+");
|
||||
private JButton diezButton = new JButton("#");
|
||||
|
||||
private JPanel dialPadPanel = new JPanel(new GridLayout(4, 3, 5, 5));
|
||||
|
||||
public DialPanel(){
|
||||
super(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init(){
|
||||
|
||||
oneButton.setFont(this.buttonTextFont);
|
||||
twoButton.setFont(this.buttonTextFont);
|
||||
threeButton.setFont(this.buttonTextFont);
|
||||
fourButton.setFont(this.buttonTextFont);
|
||||
fiveButton.setFont(this.buttonTextFont);
|
||||
sixButton.setFont(this.buttonTextFont);
|
||||
sevenButton.setFont(this.buttonTextFont);
|
||||
eightButton.setFont(this.buttonTextFont);
|
||||
nineButton.setFont(this.buttonTextFont);
|
||||
zeroButton.setFont(this.buttonTextFont);
|
||||
diezButton.setFont(this.buttonTextFont);
|
||||
starButton.setFont(this.buttonTextFont);
|
||||
|
||||
dialPadPanel.add(oneButton);
|
||||
dialPadPanel.add(twoButton);
|
||||
dialPadPanel.add(threeButton);
|
||||
dialPadPanel.add(fourButton);
|
||||
dialPadPanel.add(fiveButton);
|
||||
dialPadPanel.add(sixButton);
|
||||
dialPadPanel.add(sevenButton);
|
||||
dialPadPanel.add(eightButton);
|
||||
dialPadPanel.add(nineButton);
|
||||
dialPadPanel.add(starButton);
|
||||
dialPadPanel.add(zeroButton);
|
||||
dialPadPanel.add(diezButton);
|
||||
|
||||
this.add(dialPadPanel, BorderLayout.CENTER);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,284 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.customcontrols.StatusIcon;
|
||||
import net.java.sip.communicator.util.Logger;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* All look and feel related constants are stored here.
|
||||
*/
|
||||
|
||||
public class LookAndFeelConstants {
|
||||
private static Logger log = Logger.getLogger(LookAndFeelConstants.class);
|
||||
|
||||
/*========================================================================
|
||||
* ------------------------ SIZE CONSTANTS --------------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final int MAINFRAME_HEIGHT = 200;
|
||||
|
||||
public static final int MAINFRAME_WIDTH = 30;
|
||||
|
||||
public static final int CONTACTPANEL_HEIGHT = 25;
|
||||
|
||||
public static final int CONTACTPANEL_WIDTH = 10;
|
||||
|
||||
public static final int CONTACTPANEL_SELECTED_HEIGHT = 50;
|
||||
|
||||
public static final int CONTACTPANEL_SELECTED_GRADIENT_SIZE = 10;
|
||||
|
||||
public static final int CONTACTPANEL_GRADIENT_SIZE = 10;
|
||||
|
||||
|
||||
/*========================================================================
|
||||
* ------------------------ COLOR CONSTANTS -------------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final Color CONTACTPANEL_SELECTED_START_COLOR =
|
||||
new Color(166, 207, 239);
|
||||
|
||||
public static final Color CONTACTPANEL_SELECTED_END_COLOR =
|
||||
new Color(255, 255, 255);
|
||||
|
||||
public static final Color CONTACTPANEL_MOVER_START_COLOR =
|
||||
new Color(210, 210, 210);
|
||||
|
||||
// public static final Color CONTACTPANEL_MOVER_START_COLOR =
|
||||
// new Color(244, 235, 143);
|
||||
|
||||
public static final Color CONTACTPANEL_MOVER_END_COLOR =
|
||||
new Color(255, 255, 255);
|
||||
|
||||
public static final Color CONTACTPANEL_LINES_COLOR =
|
||||
new Color(154, 154, 154);
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
* ------------------------------ ICONS ----------------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final Image QUICK_MENU_ADD_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/addContactIcon.png");
|
||||
|
||||
public static final Image QUICK_MENU_CONFIGURE_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/configureIcon.png");
|
||||
|
||||
public static final Image QUICK_MENU_BUTTON_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/quickMenuButtonBg.gif");
|
||||
|
||||
public static final Image QUICK_MENU_BUTTON_ROLLOVER_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/quickMenuButtonRolloverBg.gif");
|
||||
|
||||
public static final Image CALL_BUTTON_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/callIcon.png");
|
||||
|
||||
public static final Image HANG_UP_BUTTON_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/hangupIcon.png");
|
||||
|
||||
public static final Image CALL_BUTTON_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/call.gif");
|
||||
|
||||
public static final Image HANGUP_BUTTON_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/hangUp.gif");
|
||||
|
||||
public static final Image CALL_ROLLOVER_BUTTON_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/callRollover.gif");
|
||||
|
||||
public static final Image HANGUP_ROLLOVER_BUTTON_BG = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/hangUpRollover.gif");
|
||||
|
||||
public static final Image STATUS_SELECTOR_BOX = LookAndFeelConstants
|
||||
.loadImage("../resources/buttons/combobox.png");
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
* ------------------------ STATUS LABELS ---------------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final String ONLINE_STATUS = "Online";
|
||||
|
||||
public static final String OFFLINE_STATUS = "Offline";
|
||||
|
||||
public static final String OCCUPIED_STATUS = "Occupied";
|
||||
|
||||
public static final String CHAT_STATUS = "Free for chat";
|
||||
|
||||
public static final String AWAY_STATUS = "Away";
|
||||
|
||||
public static final String NA_STATUS = "Not available";
|
||||
|
||||
public static final String INVISIBLE_STATUS = "Invisible";
|
||||
|
||||
public static final String DND_STATUS = "Do not disturb";
|
||||
|
||||
/*=========================================================================
|
||||
* ------------------------ PROTOCOL NAMES --------------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final String ICQ = "ICQ";
|
||||
|
||||
public static final String MSN = "MSN";
|
||||
|
||||
public static final String AIM = "AIM";
|
||||
|
||||
public static final String YAHOO = "Yahoo";
|
||||
|
||||
public static final String JABBER = "Jabber";
|
||||
|
||||
public static final String SKYPE = "Skype";
|
||||
|
||||
/*=========================================================================
|
||||
* --------------------- PROTOCOLS STATUS ICONS ---------------------------
|
||||
========================================================================*/
|
||||
|
||||
public static final Image ICQ_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/Icq16.png");
|
||||
|
||||
public static final Image ICQ_FF_CHAT_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_ffc.png");
|
||||
|
||||
public static final Image ICQ_AWAY_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_away.png");
|
||||
|
||||
public static final Image ICQ_NA_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_na.png");
|
||||
|
||||
public static final Image ICQ_DND_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_dnd.png");
|
||||
|
||||
public static final Image ICQ_OCCUPIED_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_occupied.png");
|
||||
|
||||
public static final Image ICQ_OFFLINE_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_offline.png");
|
||||
|
||||
public static final Image ICQ_INVISIBLE_ICON = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/icq/cr16-action-icq_invisible.png");
|
||||
|
||||
public static final Image MSN_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/msn/Msn16.png");
|
||||
|
||||
public static final Image AIM_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/aim/Aim16.png");
|
||||
|
||||
public static final Image YAHOO_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/yahoo/Yahoo16.png");
|
||||
|
||||
public static final Image JABBER_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/jabber/Jabber16.png");
|
||||
|
||||
public static final Image SKYPE_LOGO = LookAndFeelConstants
|
||||
.loadImage("../resources/protocols/skype/Skype16.png");
|
||||
|
||||
|
||||
/**
|
||||
* Gets all protocol statuses, including status and text.
|
||||
*
|
||||
* @param protocolName
|
||||
* @return an ArrayList of all status Icons for the given protocol.
|
||||
*/
|
||||
|
||||
public static ArrayList getProtocolIcons (String protocolName) {
|
||||
ArrayList protocolStatusList = new ArrayList ();
|
||||
|
||||
if (protocolName.equals (LookAndFeelConstants.ICQ)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO)));
|
||||
|
||||
protocolStatusList.add (new Status(CHAT_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO,
|
||||
LookAndFeelConstants.ICQ_FF_CHAT_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(AWAY_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO,
|
||||
LookAndFeelConstants.ICQ_AWAY_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(NA_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO,
|
||||
LookAndFeelConstants.ICQ_NA_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(DND_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO,
|
||||
LookAndFeelConstants.ICQ_DND_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(OCCUPIED_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_LOGO,
|
||||
LookAndFeelConstants.ICQ_OCCUPIED_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(OFFLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_OFFLINE_ICON)));
|
||||
|
||||
protocolStatusList.add(new Status(INVISIBLE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.ICQ_INVISIBLE_ICON)));
|
||||
|
||||
} else if (protocolName.equals (LookAndFeelConstants.MSN)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.MSN_LOGO)));
|
||||
|
||||
} else if (protocolName.equals (LookAndFeelConstants.AIM)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.AIM_LOGO)));
|
||||
|
||||
} else if (protocolName.equals (LookAndFeelConstants.YAHOO)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.YAHOO_LOGO)));
|
||||
|
||||
} else if (protocolName.equals (LookAndFeelConstants.JABBER)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.JABBER_LOGO)));
|
||||
|
||||
} else if (protocolName.equals (LookAndFeelConstants.SKYPE)) {
|
||||
|
||||
protocolStatusList.add (new Status(ONLINE_STATUS,
|
||||
new StatusIcon (LookAndFeelConstants.SKYPE_LOGO)));
|
||||
}
|
||||
|
||||
return protocolStatusList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an image from a given path.
|
||||
*/
|
||||
|
||||
private static Image loadImage(String path) {
|
||||
Image image = null;
|
||||
|
||||
try {
|
||||
log.logEntry();
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Loading image : " + path + "...");
|
||||
}
|
||||
|
||||
image = ImageIO.read(LookAndFeelConstants.class.getResource(path));
|
||||
|
||||
if (log.isTraceEnabled()) {
|
||||
log.trace("Loading image : " + path + "... [ DONE ]");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Failed to load image:" + path, e);
|
||||
} finally {
|
||||
log.logExit();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The MainFrame of the application.
|
||||
*/
|
||||
public class MainFrame extends JFrame{
|
||||
|
||||
private JPanel mainPanel = new JPanel(new BorderLayout());
|
||||
private JPanel menusPanel = new JPanel(new BorderLayout());
|
||||
private Menu menu = new Menu();
|
||||
private QuickMenu quickMenu = new QuickMenu();
|
||||
private CallPanel callPanel = new CallPanel();
|
||||
private StatusPanel statusPanel;
|
||||
private MainTabbedPane tabbedPane;
|
||||
|
||||
|
||||
public MainFrame(ContactList clist, User user){
|
||||
tabbedPane = new MainTabbedPane(clist);
|
||||
statusPanel = new StatusPanel(user.getProtocols());
|
||||
|
||||
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
this.setInitialBounds();
|
||||
// this.setIconImage();
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
this.menusPanel.add(menu, BorderLayout.NORTH);
|
||||
this.menusPanel.add(quickMenu, BorderLayout.CENTER);
|
||||
|
||||
this.mainPanel.add(tabbedPane, BorderLayout.CENTER);
|
||||
this.mainPanel.add(callPanel, BorderLayout.SOUTH);
|
||||
|
||||
this.getContentPane().add(menusPanel, BorderLayout.NORTH);
|
||||
this.getContentPane().add(mainPanel, BorderLayout.CENTER);
|
||||
this.getContentPane().add(statusPanel, BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
private void setInitialBounds(){
|
||||
this.setLocation(Toolkit.getDefaultToolkit().getScreenSize().width - MainFrame.WIDTH, 50);
|
||||
|
||||
this.getContentPane().setSize( LookAndFeelConstants.MAINFRAME_WIDTH,
|
||||
LookAndFeelConstants.MAINFRAME_HEIGHT);
|
||||
|
||||
this.tabbedPane.setPreferredSize(new Dimension(LookAndFeelConstants.MAINFRAME_WIDTH,
|
||||
LookAndFeelConstants.MAINFRAME_HEIGHT));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.event.ListDataListener;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The main tabbed pane containing the contact list panel, the
|
||||
* call list panel and the dial panel.
|
||||
*/
|
||||
public class MainTabbedPane extends JTabbedPane {
|
||||
|
||||
private DialPanel dialPanel = new DialPanel();
|
||||
|
||||
public MainTabbedPane(ContactList clist){
|
||||
|
||||
ContactListPanel contactList = new ContactListPanel(clist);
|
||||
|
||||
this.addTab("Contacts", contactList);
|
||||
this.addTab("Call list", new JPanel());
|
||||
this.addTab("Dial", dialPanel);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The main menu.
|
||||
*/
|
||||
public class Menu extends JMenuBar {
|
||||
private JMenu userMenu = new JMenu();
|
||||
private JMenu toolsMenu = new JMenu();
|
||||
private JMenu viewMenu = new JMenu();
|
||||
private JMenu helpMenu = new JMenu();
|
||||
|
||||
public Menu(){
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init(){
|
||||
userMenu.setText("User");
|
||||
userMenu.setMnemonic('U');
|
||||
userMenu.setToolTipText("User");
|
||||
|
||||
toolsMenu.setText("Tools");
|
||||
toolsMenu.setMnemonic('T');
|
||||
toolsMenu.setToolTipText("Tools");
|
||||
|
||||
viewMenu.setText("View");
|
||||
viewMenu.setMnemonic('V');
|
||||
viewMenu.setToolTipText("View");
|
||||
|
||||
helpMenu.setText("Help");
|
||||
helpMenu.setMnemonic('H');
|
||||
helpMenu.setToolTipText("Help");
|
||||
|
||||
this.add(userMenu);
|
||||
this.add(toolsMenu);
|
||||
this.add(viewMenu);
|
||||
this.add(helpMenu);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JToolBar;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.customcontrols.SIPCommButton;
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The quick menu.
|
||||
*/
|
||||
public class QuickMenu extends JToolBar{
|
||||
|
||||
private Image addButtonIcon = LookAndFeelConstants.QUICK_MENU_ADD_ICON;
|
||||
private Image configureButtonIcon = LookAndFeelConstants.QUICK_MENU_CONFIGURE_ICON;
|
||||
|
||||
SIPCommButton infoButton;
|
||||
SIPCommButton toolsButton;
|
||||
SIPCommButton addButton;
|
||||
SIPCommButton searchButton;
|
||||
|
||||
public QuickMenu(){
|
||||
|
||||
this.setRollover(true);
|
||||
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
|
||||
|
||||
infoButton = new SIPCommButton();
|
||||
toolsButton = new SIPCommButton(configureButtonIcon);
|
||||
searchButton = new SIPCommButton();
|
||||
addButton = new SIPCommButton(addButtonIcon);
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.add(addButton);
|
||||
this.add(toolsButton);
|
||||
this.add(infoButton);
|
||||
this.add(searchButton);
|
||||
}
|
||||
|
||||
public void paint(Graphics g){
|
||||
super.paint(g);
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g;
|
||||
|
||||
GradientPaint p = new GradientPaint(this.getWidth()/2,
|
||||
0,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_START_COLOR,
|
||||
this.getWidth()/2,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_GRADIENT_SIZE,
|
||||
LookAndFeelConstants.CONTACTPANEL_SELECTED_END_COLOR);
|
||||
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
|
||||
g2.setPaint(p);
|
||||
|
||||
//g2.dra
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.Image;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
public class Status {
|
||||
|
||||
private String text;
|
||||
private Image icon;
|
||||
|
||||
public Status(String text, Image icon){
|
||||
this.text = text;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public Image getIcon () {
|
||||
return icon;
|
||||
}
|
||||
public void setIcon (Image icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
public String getText () {
|
||||
return text;
|
||||
}
|
||||
public void setText (String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.customcontrols.SIPCommButton;
|
||||
import net.java.sip.communicator.impl.gui.main.customcontrols.StatusSelectorBox;
|
||||
|
||||
public class StatusPanel extends JPanel {
|
||||
|
||||
private String[] userProtocols;
|
||||
|
||||
public StatusPanel(String[] userProtocols) {
|
||||
|
||||
this.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||
this.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,
|
||||
LookAndFeelConstants.CONTACTPANEL_MOVER_START_COLOR));
|
||||
|
||||
this.userProtocols = userProtocols;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
||||
for (int i = 0; i < userProtocols.length; i++) {
|
||||
|
||||
ArrayList protocolStatusList = LookAndFeelConstants
|
||||
.getProtocolIcons(userProtocols[i]);
|
||||
|
||||
StatusSelectorBox protocolStatusCombo = new StatusSelectorBox(
|
||||
protocolStatusList.toArray(), (Status)protocolStatusList.get(0));
|
||||
|
||||
this.add(protocolStatusCombo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package net.java.sip.communicator.impl.gui.main;
|
||||
|
||||
public class User {
|
||||
private String[] userProtocols;
|
||||
|
||||
public void setProtocols(String[] userProtocols){
|
||||
this.userProtocols = userProtocols;
|
||||
}
|
||||
|
||||
public String[] getProtocols(){
|
||||
return this.userProtocols;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
package net.java.sip.communicator.impl.gui.main.customcontrols;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.LookAndFeelConstants;
|
||||
|
||||
/**
|
||||
* @author Yana Stamcheva
|
||||
*
|
||||
* The quick menu is composed of special buttons, which are specified here.
|
||||
*/
|
||||
public class SIPCommButton extends JButton {
|
||||
|
||||
private Image bgImage;
|
||||
|
||||
private Image bgRolloverImage;
|
||||
|
||||
private Image iconImage;
|
||||
|
||||
public SIPCommButton() {
|
||||
super();
|
||||
|
||||
this.bgImage = LookAndFeelConstants.QUICK_MENU_BUTTON_BG;
|
||||
this.bgRolloverImage = LookAndFeelConstants.QUICK_MENU_BUTTON_ROLLOVER_BG;
|
||||
this.setIcon(new ImageIcon(this.bgImage));
|
||||
|
||||
this.setPreferredSize(new Dimension(this.bgImage.getWidth(null),
|
||||
this.bgImage.getHeight(null)));
|
||||
}
|
||||
|
||||
public SIPCommButton(String text) {
|
||||
super(text);
|
||||
|
||||
this.bgImage = LookAndFeelConstants.QUICK_MENU_BUTTON_BG;
|
||||
this.bgRolloverImage = LookAndFeelConstants.QUICK_MENU_BUTTON_ROLLOVER_BG;
|
||||
|
||||
this.setPreferredSize(new Dimension(this.bgImage.getWidth(null),
|
||||
this.bgImage.getHeight(null)));
|
||||
}
|
||||
|
||||
public SIPCommButton(Image iconImage) {
|
||||
super();
|
||||
|
||||
this.iconImage = iconImage;
|
||||
this.bgImage = LookAndFeelConstants.QUICK_MENU_BUTTON_BG;
|
||||
this.bgRolloverImage = LookAndFeelConstants.QUICK_MENU_BUTTON_ROLLOVER_BG;
|
||||
|
||||
this.setPreferredSize(new Dimension(this.bgImage.getWidth(null),
|
||||
this.bgImage.getHeight(null)));
|
||||
|
||||
this.setIcon(new ImageIcon(this.bgImage));
|
||||
}
|
||||
|
||||
public SIPCommButton(Image bgImage, Image rolloverImage, Image iconImage) {
|
||||
super();
|
||||
|
||||
this.iconImage = iconImage;
|
||||
this.bgImage = bgImage;
|
||||
this.bgRolloverImage = rolloverImage;
|
||||
|
||||
this.setPreferredSize(new Dimension(this.bgImage.getWidth(null),
|
||||
this.bgImage.getHeight(null)));
|
||||
|
||||
this.setIcon(new ImageIcon(this.bgImage));
|
||||
}
|
||||
|
||||
public void paint(Graphics g) {
|
||||
|
||||
g.drawImage(this.bgImage, 0, 0, this);
|
||||
|
||||
if (this.iconImage != null) {
|
||||
|
||||
g.drawImage(this.iconImage,
|
||||
(this.bgImage.getWidth(null) -
|
||||
this.iconImage.getWidth(null)) / 2,
|
||||
(this.bgImage.getHeight(null) -
|
||||
this.iconImage.getHeight(null)) / 2, this);
|
||||
}
|
||||
|
||||
if (this.getModel().isRollover()) {
|
||||
|
||||
g.setColor(LookAndFeelConstants.CONTACTPANEL_LINES_COLOR);
|
||||
g.drawImage(this.bgRolloverImage, 0, 0, this);
|
||||
|
||||
if (this.iconImage != null) {
|
||||
|
||||
g.drawImage(this.iconImage,
|
||||
(this.bgImage.getWidth(null) -
|
||||
this.iconImage.getWidth(null)) / 2,
|
||||
(this.bgImage.getHeight(null) -
|
||||
this.iconImage.getHeight(null)) / 2, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Image getBgImage() {
|
||||
return bgImage;
|
||||
}
|
||||
|
||||
public void setBgImage(Image bgImage) {
|
||||
this.bgImage = bgImage;
|
||||
}
|
||||
|
||||
public Image getBgRolloverImage() {
|
||||
return bgRolloverImage;
|
||||
}
|
||||
|
||||
public void setBgRolloverImage(Image bgRolloverImage) {
|
||||
this.bgRolloverImage = bgRolloverImage;
|
||||
}
|
||||
|
||||
public Image getIconImage() {
|
||||
return iconImage;
|
||||
}
|
||||
|
||||
public void setIconImage(Image iconImage) {
|
||||
this.iconImage = iconImage;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package net.java.sip.communicator.impl.gui.main.customcontrols;
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class StatusIcon extends BufferedImage {
|
||||
|
||||
private Image bgImage;
|
||||
private Image iconImage;
|
||||
|
||||
|
||||
public StatusIcon (Image bgImage, Image iconImage) {
|
||||
super( bgImage.getWidth(null),
|
||||
bgImage.getHeight(null),
|
||||
BufferedImage.TYPE_4BYTE_ABGR);
|
||||
|
||||
this.bgImage = bgImage;
|
||||
this.iconImage = iconImage;
|
||||
|
||||
this.getGraphics().drawImage (this.bgImage, 0, 0, null);
|
||||
|
||||
if (this.iconImage != null)
|
||||
this.getGraphics().drawImage (this.iconImage,
|
||||
(this.bgImage.getWidth(null) -
|
||||
this.iconImage.getWidth(null)) / 2,
|
||||
(this.bgImage.getHeight(null) -
|
||||
this.iconImage.getHeight(null)) / 2, null);
|
||||
|
||||
}
|
||||
|
||||
public StatusIcon (Image image) {
|
||||
super( image.getWidth(null),
|
||||
image.getHeight(null),
|
||||
BufferedImage.TYPE_4BYTE_ABGR);
|
||||
|
||||
this.bgImage = image;
|
||||
|
||||
this.getGraphics().drawImage (this.bgImage, 0, 0, null);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,117 @@
|
||||
package net.java.sip.communicator.impl.gui.main.customcontrols;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Image;
|
||||
import java.awt.MenuItem;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
|
||||
import net.java.sip.communicator.impl.gui.main.LookAndFeelConstants;
|
||||
import net.java.sip.communicator.impl.gui.main.Status;
|
||||
|
||||
public class StatusSelectorBox extends SIPCommButton
|
||||
implements ActionListener{
|
||||
|
||||
private SIPCommButton button;
|
||||
|
||||
private JPopupMenu popup;
|
||||
|
||||
private Object[] items;
|
||||
|
||||
private final Image statusSelectorBg = LookAndFeelConstants.STATUS_SELECTOR_BOX;
|
||||
|
||||
private final int width = statusSelectorBg.getWidth(null);
|
||||
|
||||
private final int height = statusSelectorBg.getHeight(null);
|
||||
|
||||
private final int iconX = (this.width - 24) / 2;
|
||||
|
||||
private final int iconY = (this.height - 16) / 2;
|
||||
|
||||
public StatusSelectorBox(Object[] items, Status currentStatus) {
|
||||
|
||||
super( LookAndFeelConstants.STATUS_SELECTOR_BOX,
|
||||
LookAndFeelConstants.STATUS_SELECTOR_BOX,
|
||||
currentStatus.getIcon());
|
||||
|
||||
this.popup = new JPopupMenu();
|
||||
|
||||
this.items = items;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
|
||||
if (items[i] instanceof Status) {
|
||||
|
||||
Status status = (Status) items[i];
|
||||
JMenuItem item = new JMenuItem( status.getText(),
|
||||
new ImageIcon(status.getIcon()));
|
||||
|
||||
item.addActionListener(this);
|
||||
|
||||
this.popup.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
this.popup.setInvoker(this);
|
||||
this.addActionListener(this);
|
||||
|
||||
}
|
||||
|
||||
public void actionPerformed (ActionEvent e) {
|
||||
|
||||
if (e.getSource() instanceof SIPCommButton){
|
||||
|
||||
if (!this.popup.isVisible()) {
|
||||
this.popup.setLocation(this.calculatePopupLocation());
|
||||
this.popup.setVisible(true);
|
||||
}
|
||||
}
|
||||
else if (e.getSource() instanceof JMenuItem){
|
||||
|
||||
JMenuItem menuItem = (JMenuItem) e.getSource();
|
||||
|
||||
this.setIconImage(((ImageIcon)menuItem.getIcon()).getImage());
|
||||
}
|
||||
}
|
||||
|
||||
public Point calculatePopupLocation(){
|
||||
|
||||
Component component = this;
|
||||
Point point = new Point();
|
||||
int x = this.getX();
|
||||
int y = this.getY();
|
||||
|
||||
while(component.getParent() != null){
|
||||
|
||||
component = component.getParent();
|
||||
|
||||
x += component.getX();
|
||||
y += component.getY();
|
||||
}
|
||||
|
||||
point.x = x;
|
||||
point.y = y + this.getHeight();
|
||||
|
||||
return point;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 630 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 840 B |
|
After Width: | Height: | Size: 892 B |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 624 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 737 B |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 817 B |
|
After Width: | Height: | Size: 360 B |
|
After Width: | Height: | Size: 666 B |
|
After Width: | Height: | Size: 884 B |
|
After Width: | Height: | Size: 1009 B |
|
After Width: | Height: | Size: 387 B |
|
After Width: | Height: | Size: 761 B |
|
After Width: | Height: | Size: 643 B |
|
After Width: | Height: | Size: 807 B |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 920 B |