/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package net.java.sip.communicator.plugin.advancedconfig;
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.service.gui.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import org.osgi.framework.*;
/**
* The advanced configuration panel.
*
* @author Yana Stamcheva
*/
public class AdvancedConfigurationPanel
extends TransparentPanel
implements ConfigurationForm,
ConfigurationContainer,
ServiceListener,
ListSelectionListener
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 0L;
/**
* The Logger used by this AdvancedConfigurationPanel for
* logging output.
*/
private final Logger logger
= Logger.getLogger(AdvancedConfigurationPanel.class);
/**
* The configuration list.
*/
private final JList configList = new JList();
/**
* The center panel.
*/
private final JPanel centerPanel = new TransparentPanel(new BorderLayout());
/**
* Creates an instance of the AdvancedConfigurationPanel.
*/
public AdvancedConfigurationPanel()
{
super(new BorderLayout(10, 0));
initList();
centerPanel.setPreferredSize(new Dimension(500, 500));
add(centerPanel, BorderLayout.CENTER);
}
/**
* Initializes the config list.
*/
private void initList()
{
configList.setModel(new DefaultListModel());
configList.setCellRenderer(new ConfigListCellRenderer());
configList.addListSelectionListener(this);
configList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane configScrollList = new JScrollPane();
configScrollList.getVerticalScrollBar().setUnitIncrement(30);
configScrollList.getViewport().add(configList);
add(configScrollList, BorderLayout.WEST);
String osgiFilter = "("
+ ConfigurationForm.FORM_TYPE
+ "="+ConfigurationForm.ADVANCED_TYPE+")";
ServiceReference[] confFormsRefs = null;
try
{
confFormsRefs = AdvancedConfigActivator.bundleContext
.getServiceReferences( ConfigurationForm.class.getName(),
osgiFilter);
}
catch (InvalidSyntaxException ex)
{}
if(confFormsRefs != null)
{
for (int i = 0; i < confFormsRefs.length; i++)
{
ConfigurationForm form
= (ConfigurationForm) AdvancedConfigActivator.bundleContext
.getService(confFormsRefs[i]);
if (form.isAdvanced())
this.addConfigForm(form);
}
}
}
/**
* Shows on the right the configuration form given by the given
* ConfigFormDescriptor.
*
* @param configForm the configuration form to show
*/
private void showFormContent(ConfigurationForm configForm)
{
this.centerPanel.removeAll();
JComponent configFormPanel
= (JComponent) configForm.getForm();
configFormPanel.setOpaque(false);
this.centerPanel.add(configFormPanel, BorderLayout.CENTER);
this.centerPanel.revalidate();
this.centerPanel.repaint();
}
/**
* Handles registration of a new configuration form.
* @param event the ServiceEvent that notified us
*/
public void serviceChanged(ServiceEvent event)
{
Object sService
= AdvancedConfigActivator.bundleContext
.getService(event.getServiceReference());
// we don't care if the source service is not a configuration form
if (!(sService instanceof ConfigurationForm))
return;
ConfigurationForm configForm = (ConfigurationForm) sService;
/*
* This AdvancedConfigurationPanel is an advanced ConfigurationForm so
* don't try to add it to itself.
*/
if ((configForm == this) || !configForm.isAdvanced())
return;
switch (event.getType())
{
case ServiceEvent.REGISTERED:
if (logger.isInfoEnabled())
logger.info("Handling registration of a new Configuration Form.");
this.addConfigForm(configForm);
break;
case ServiceEvent.UNREGISTERING:
this.removeConfigForm(configForm);
break;
}
}
/**
* Adds a new ConfigurationForm to this list.
* @param configForm The ConfigurationForm to add.
*/
public void addConfigForm(ConfigurationForm configForm)
{
if (configForm == null)
throw new IllegalArgumentException("configForm");
DefaultListModel listModel = (DefaultListModel) configList.getModel();
int i = 0;
int count = listModel.getSize();
int configFormIndex = configForm.getIndex();
for (; i < count; i++)
{
ConfigurationForm form = (ConfigurationForm) listModel.get(i);
if (configFormIndex < form.getIndex())
break;
}
listModel.add(i, configForm);
}
/**
* Implements ApplicationWindow.show
method.
*
* @param isVisible specifies whether the frame is to be visible or not.
*/
@Override
public void setVisible(boolean isVisible)
{
if (isVisible && configList.getSelectedIndex() < 0)
{
this.configList.setSelectedIndex(0);
}
super.setVisible(isVisible);
}
/**
* Removes a ConfigurationForm from this list.
* @param configForm The ConfigurationForm to remove.
*/
public void removeConfigForm(ConfigurationForm configForm)
{
DefaultListModel listModel = (DefaultListModel) configList.getModel();
for(int count = listModel.getSize(), i = count - 1; i >= 0; i--)
{
ConfigurationForm form
= (ConfigurationForm) listModel.get(i);
if(form.equals(configForm))
{
listModel.remove(i);
/*
* TODO We may just consider not allowing duplicates on addition
* and then break here.
*/
}
}
}
/**
* A custom cell renderer that represents a ConfigurationForm.
*/
private class ConfigListCellRenderer extends DefaultListCellRenderer
{
/**
* Serial version UID.
*/
private static final long serialVersionUID = 0L;
private boolean isSelected = false;
private final Color selectedColor
= new Color(AdvancedConfigActivator.getResources().
getColor("service.gui.LIST_SELECTION_COLOR"));
/**
* Creates an instance of ConfigListCellRenderer and specifies
* that this renderer is transparent.
*/
public ConfigListCellRenderer()
{
this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
this.setOpaque(false);
}
/**
* Returns the component representing the cell given by parameters.
* @param list the parent list
* @param value the value of the cell
* @param index the index of the cell
* @param isSelected indicates if the cell is selected
* @param cellHasFocus indicates if the cell has the focus
* @return the component representing the cell
*/
public Component getListCellRendererComponent( JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
ConfigurationForm configForm = (ConfigurationForm) value;
this.isSelected = isSelected;
this.setText(configForm.getTitle());
return this;
}
/**
* Paint a background for all groups and a round blue border and
* background when a cell is selected.
* @param g the Graphics object
*/
public void paintComponent(Graphics g)
{
Graphics g2 = g.create();
try
{
internalPaintComponent(g2);
}
finally
{
g2.dispose();
}
super.paintComponent(g);
}
/**
* Paint a background for all groups and a round blue border and
* background when a cell is selected.
* @param g the Graphics object
*/
private void internalPaintComponent(Graphics g)
{
AntialiasingManager.activateAntialiasing(g);
Graphics2D g2 = (Graphics2D) g;
if (isSelected)
{
g2.setColor(selectedColor);
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
}
}
}
/**
* Called when user selects a component in the list of configuration forms.
* @param e the ListSelectionEvent
*/
public void valueChanged(ListSelectionEvent e)
{
if(!e.getValueIsAdjusting())
{
ConfigurationForm configForm
= (ConfigurationForm) configList.getSelectedValue();
if(configForm != null)
showFormContent(configForm);
}
}
/**
* Selects the given ConfigurationForm.
*
* @param configForm the ConfigurationForm to select
*/
public void setSelected(ConfigurationForm configForm)
{
configList.setSelectedValue(configForm, true);
}
/**
* Returns the title of the form.
* @return the title of the form
*/
public String getTitle()
{
return AdvancedConfigActivator.getResources()
.getI18NString("service.gui.ADVANCED");
}
/**
* Returns the icon of the form.
* @return a byte array containing the icon of the form
*/
public byte[] getIcon()
{
return AdvancedConfigActivator.getResources()
.getImageInBytes("plugin.advancedconfig.PLUGIN_ICON");
}
/**
* Returns the form component.
* @return the form component
*/
public Object getForm()
{
return this;
}
/**
* Returns the index of the form in its parent container.
* @return the index of the form in its parent container
*/
public int getIndex()
{
return 300;
}
/**
* Indicates if the form is an advanced form.
* @return true to indicate that this is an advanced form,
* otherwise returns false
*/
public boolean isAdvanced()
{
return false;
}
/**
* Validates the currently selected configuration form. This method is meant
* to be used by configuration forms the re-validate when a new component
* has been added or size has changed.
*/
public void validateCurrentForm() {}
}