mirror of https://github.com/sipwise/jitsi.git
parent
ca841c75cc
commit
296d1e0f1b
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* 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.media;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.media.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import net.java.sip.communicator.impl.media.device.*;
|
||||
|
||||
/**
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class DeviceConfigurationComboBoxModel
|
||||
implements ComboBoxModel
|
||||
{
|
||||
public static class CaptureDevice
|
||||
{
|
||||
public final CaptureDeviceInfo info;
|
||||
|
||||
public CaptureDevice(CaptureDeviceInfo info)
|
||||
{
|
||||
if (info == null)
|
||||
throw new IllegalArgumentException("info");
|
||||
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return info.getName();
|
||||
}
|
||||
}
|
||||
|
||||
public static final int AUDIO = 1;
|
||||
|
||||
private static final CaptureDevice[] NO_CAPTURE_DEVICES =
|
||||
new CaptureDevice[0];
|
||||
|
||||
public static final int VIDEO = 2;
|
||||
|
||||
private final DeviceConfiguration deviceConfiguration;
|
||||
|
||||
private CaptureDevice[] devices;
|
||||
|
||||
private final List<ListDataListener> listeners =
|
||||
new ArrayList<ListDataListener>();
|
||||
|
||||
private final int type;
|
||||
|
||||
public DeviceConfigurationComboBoxModel(
|
||||
DeviceConfiguration deviceConfiguration, int type)
|
||||
{
|
||||
if (deviceConfiguration == null)
|
||||
throw new IllegalArgumentException("deviceConfiguration");
|
||||
if ((type != AUDIO) && (type != VIDEO))
|
||||
throw new IllegalArgumentException("type");
|
||||
|
||||
this.deviceConfiguration = deviceConfiguration;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public void addListDataListener(ListDataListener listener)
|
||||
{
|
||||
if (listener == null)
|
||||
throw new IllegalArgumentException("listener");
|
||||
|
||||
if (!listeners.contains(listener))
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
protected void fireContentsChanged(int index0, int index1)
|
||||
{
|
||||
ListDataListener[] listeners =
|
||||
this.listeners.toArray(new ListDataListener[this.listeners.size()]);
|
||||
ListDataEvent event =
|
||||
new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, index0,
|
||||
index1);
|
||||
|
||||
for (int i = 0; i < listeners.length; i++)
|
||||
{
|
||||
listeners[i].contentsChanged(event);
|
||||
}
|
||||
}
|
||||
|
||||
private DeviceConfiguration getDeviceConfiguration()
|
||||
{
|
||||
return deviceConfiguration;
|
||||
}
|
||||
|
||||
private CaptureDevice[] getDevices()
|
||||
{
|
||||
if (devices != null)
|
||||
return devices;
|
||||
|
||||
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
|
||||
CaptureDeviceInfo[] infos;
|
||||
switch (type)
|
||||
{
|
||||
case AUDIO:
|
||||
infos = deviceConfiguration.getAvailableAudioCaptureDevices();
|
||||
break;
|
||||
case VIDEO:
|
||||
infos = deviceConfiguration.getAvailableVideoCaptureDevices();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("type");
|
||||
}
|
||||
|
||||
final int deviceCount = infos.length;
|
||||
if (deviceCount < 1)
|
||||
devices = NO_CAPTURE_DEVICES;
|
||||
else
|
||||
{
|
||||
devices = new CaptureDevice[deviceCount];
|
||||
for (int i = 0; i < deviceCount; i++)
|
||||
{
|
||||
devices[i] = new CaptureDevice(infos[i]);
|
||||
}
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
public Object getElementAt(int index)
|
||||
{
|
||||
return getDevices()[index];
|
||||
}
|
||||
|
||||
private CaptureDevice getSelectedDevice()
|
||||
{
|
||||
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
|
||||
CaptureDeviceInfo info;
|
||||
switch (type)
|
||||
{
|
||||
case AUDIO:
|
||||
info = deviceConfiguration.getAudioCaptureDevice();
|
||||
break;
|
||||
case VIDEO:
|
||||
info = deviceConfiguration.getVideoCaptureDevice();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("type");
|
||||
}
|
||||
|
||||
CaptureDevice[] devices = getDevices();
|
||||
for (int i = 0; i < devices.length; i++)
|
||||
{
|
||||
CaptureDevice device = devices[i];
|
||||
if (device.info.equals(info))
|
||||
{
|
||||
return device;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getSelectedItem()
|
||||
{
|
||||
return getSelectedDevice();
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return getDevices().length;
|
||||
}
|
||||
|
||||
public void removeListDataListener(ListDataListener listener)
|
||||
{
|
||||
if (listener == null)
|
||||
throw new IllegalArgumentException("listener");
|
||||
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private void setSelectedDevice(CaptureDevice device)
|
||||
{
|
||||
// We cannot clear the selection of DeviceConfiguration.
|
||||
if (device == null)
|
||||
return;
|
||||
|
||||
CaptureDevice selectedDevice = getSelectedDevice();
|
||||
if (selectedDevice != device)
|
||||
{
|
||||
DeviceConfiguration deviceConfiguration = getDeviceConfiguration();
|
||||
switch (type)
|
||||
{
|
||||
case AUDIO:
|
||||
deviceConfiguration.setAudioCaptureDevice(device.info);
|
||||
break;
|
||||
case VIDEO:
|
||||
deviceConfiguration.setVideoCaptureDevice(device.info);
|
||||
break;
|
||||
}
|
||||
|
||||
fireContentsChanged(-1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectedItem(Object item)
|
||||
{
|
||||
setSelectedDevice((CaptureDevice) item);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* 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.media;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.table.*;
|
||||
|
||||
import net.java.sip.communicator.impl.media.codec.*;
|
||||
|
||||
/**
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class EncodingConfigurationTableModel
|
||||
extends AbstractTableModel
|
||||
{
|
||||
public static final int AUDIO = DeviceConfigurationComboBoxModel.AUDIO;
|
||||
|
||||
private static final String[] NO_ENCODINGS = new String[0];
|
||||
|
||||
public static final int VIDEO = DeviceConfigurationComboBoxModel.VIDEO;
|
||||
|
||||
private final EncodingConfiguration encodingConfiguration;
|
||||
|
||||
private String[] encodings;
|
||||
|
||||
private final int type;
|
||||
|
||||
public EncodingConfigurationTableModel(
|
||||
EncodingConfiguration encodingConfiguration, int type)
|
||||
{
|
||||
if (encodingConfiguration == null)
|
||||
throw new IllegalArgumentException("encodingConfiguration");
|
||||
if ((type != AUDIO) && (type != VIDEO))
|
||||
throw new IllegalArgumentException("type");
|
||||
|
||||
this.encodingConfiguration = encodingConfiguration;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Class<?> getColumnClass(int columnIndex)
|
||||
{
|
||||
return (columnIndex == 0) ? Boolean.class : super
|
||||
.getColumnClass(columnIndex);
|
||||
}
|
||||
|
||||
public int getColumnCount()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
private String[] getEncodings()
|
||||
{
|
||||
if (encodings != null)
|
||||
return encodings;
|
||||
|
||||
String[] availableEncodings;
|
||||
switch (type)
|
||||
{
|
||||
case AUDIO:
|
||||
availableEncodings =
|
||||
encodingConfiguration.getAvailableAudioEncodings();
|
||||
break;
|
||||
case VIDEO:
|
||||
availableEncodings =
|
||||
encodingConfiguration.getAvailableVideoEncodings();
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("type");
|
||||
}
|
||||
|
||||
final int encodingCount = availableEncodings.length;
|
||||
if (encodingCount < 1)
|
||||
encodings = NO_ENCODINGS;
|
||||
else
|
||||
{
|
||||
encodings = new String[encodingCount];
|
||||
System
|
||||
.arraycopy(availableEncodings, 0, encodings, 0, encodingCount);
|
||||
Arrays.sort(encodings, 0, encodingCount, new Comparator<String>()
|
||||
{
|
||||
public int compare(String encoding0, String encoding1)
|
||||
{
|
||||
if (encodingConfiguration.getPriority(encoding0) > encodingConfiguration
|
||||
.getPriority(encoding1))
|
||||
return -1;
|
||||
return encoding0.compareTo(encoding1);
|
||||
}
|
||||
});
|
||||
}
|
||||
return encodings;
|
||||
}
|
||||
|
||||
private int[] getPriorities()
|
||||
{
|
||||
String[] encodings = getEncodings();
|
||||
final int count = encodings.length;
|
||||
int[] priorities = new int[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int priority = encodingConfiguration.getPriority(encodings[i]);
|
||||
priorities[i] = (priority > 0) ? (count - i) : 0;
|
||||
}
|
||||
return priorities;
|
||||
}
|
||||
|
||||
public int getRowCount()
|
||||
{
|
||||
return getEncodings().length;
|
||||
}
|
||||
|
||||
public Object getValueAt(int rowIndex, int columnIndex)
|
||||
{
|
||||
String encoding = getEncodings()[rowIndex];
|
||||
switch (columnIndex)
|
||||
{
|
||||
case 0:
|
||||
return Boolean
|
||||
.valueOf(encodingConfiguration.getPriority(encoding) > 0);
|
||||
case 1:
|
||||
return MediaUtils.sdpToJmfEncoding(encoding);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex)
|
||||
{
|
||||
return (columnIndex == 0);
|
||||
}
|
||||
|
||||
public void move(int rowIndex, boolean up)
|
||||
{
|
||||
if (up)
|
||||
{
|
||||
if (rowIndex <= 0)
|
||||
throw new IllegalArgumentException("rowIndex");
|
||||
|
||||
move(rowIndex - 1, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowIndex >= (getRowCount() - 1))
|
||||
throw new IllegalArgumentException("rowIndex");
|
||||
|
||||
int[] priorities = getPriorities();
|
||||
final int nextRowIndex = rowIndex + 1;
|
||||
if (priorities[rowIndex] > 0)
|
||||
priorities[rowIndex] = priorities.length - nextRowIndex;
|
||||
if (priorities[nextRowIndex] > 0)
|
||||
priorities[nextRowIndex] = priorities.length - rowIndex;
|
||||
setPriorities(priorities);
|
||||
|
||||
String swap = encodings[rowIndex];
|
||||
encodings[rowIndex] = encodings[nextRowIndex];
|
||||
encodings[nextRowIndex] = swap;
|
||||
|
||||
fireTableRowsUpdated(rowIndex, nextRowIndex);
|
||||
}
|
||||
|
||||
private void setPriorities(int[] priorities)
|
||||
{
|
||||
final int count = encodings.length;
|
||||
if (priorities.length != count)
|
||||
throw new IllegalArgumentException("priorities");
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
encodingConfiguration.setPriority(encodings[i], priorities[i]);
|
||||
}
|
||||
|
||||
public void setValueAt(Object value, int rowIndex, int columnIndex)
|
||||
{
|
||||
if ((columnIndex == 0) && (value instanceof Boolean))
|
||||
{
|
||||
int[] priorities = getPriorities();
|
||||
priorities[rowIndex] =
|
||||
((Boolean) value) ? (priorities.length - rowIndex) : 0;
|
||||
setPriorities(priorities);
|
||||
|
||||
fireTableCellUpdated(rowIndex, columnIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.media;
|
||||
|
||||
import net.java.sip.communicator.service.gui.*;
|
||||
|
||||
/**
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class MediaConfigurationForm
|
||||
implements ConfigurationForm
|
||||
{
|
||||
public Object getForm()
|
||||
{
|
||||
return new MediaConfigurationPanel();
|
||||
}
|
||||
|
||||
public byte[] getIcon()
|
||||
{
|
||||
return MediaActivator.getResources().getImageInBytes(
|
||||
"MediaConfigurationForm_icon");
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
{
|
||||
return MediaActivator.getResources().getI18NString(
|
||||
"MediaConfigurationForm_title");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,429 @@
|
||||
/*
|
||||
* 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.media;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
|
||||
import javax.media.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.table.*;
|
||||
|
||||
import net.java.sip.communicator.service.media.*;
|
||||
import net.java.sip.communicator.service.resources.*;
|
||||
import net.java.sip.communicator.swing.*;
|
||||
import net.java.sip.communicator.util.*;
|
||||
|
||||
import org.osgi.framework.*;
|
||||
|
||||
/**
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class MediaConfigurationPanel
|
||||
extends JPanel
|
||||
{
|
||||
private static final int HGAP = 5;
|
||||
|
||||
private static final int VGAP = 5;
|
||||
|
||||
private static MediaServiceImpl getMediaService()
|
||||
{
|
||||
BundleContext bundleContext = MediaActivator.getBundleContext();
|
||||
ServiceReference serviceReference =
|
||||
bundleContext.getServiceReference(MediaService.class.getName());
|
||||
|
||||
return (serviceReference == null) ? null
|
||||
: (MediaServiceImpl) bundleContext.getService(serviceReference);
|
||||
}
|
||||
|
||||
private final Logger logger =
|
||||
Logger.getLogger(MediaConfigurationPanel.class);
|
||||
|
||||
private final MediaServiceImpl mediaService = getMediaService();
|
||||
|
||||
public MediaConfigurationPanel()
|
||||
{
|
||||
super(new GridLayout(0, 1, HGAP, VGAP));
|
||||
|
||||
int[] types =
|
||||
new int[]
|
||||
{ DeviceConfigurationComboBoxModel.AUDIO,
|
||||
DeviceConfigurationComboBoxModel.VIDEO };
|
||||
for (int i = 0; i < types.length; i++)
|
||||
add(createControls(types[i]));
|
||||
}
|
||||
|
||||
private void controllerUpdateForPreview(ControllerEvent event,
|
||||
Container videoContainer)
|
||||
{
|
||||
if (event instanceof RealizeCompleteEvent)
|
||||
{
|
||||
Player player = (Player) event.getSourceController();
|
||||
Component video = player.getVisualComponent();
|
||||
|
||||
showPreview(videoContainer, video, player);
|
||||
}
|
||||
}
|
||||
|
||||
private Component createControls(int type)
|
||||
{
|
||||
final JComboBox comboBox = new JComboBox();
|
||||
comboBox.setEditable(false);
|
||||
|
||||
JLabel label = new JLabel(getLabelText(type));
|
||||
label.setDisplayedMnemonic(getDisplayedMnemonic(type));
|
||||
label.setLabelFor(comboBox);
|
||||
|
||||
final JComponent preview;
|
||||
ActionListener comboBoxListener = null;
|
||||
if (type == DeviceConfigurationComboBoxModel.VIDEO)
|
||||
{
|
||||
JLabel noPreview =
|
||||
new JLabel(MediaActivator.getResources().getI18NString(
|
||||
"MediaConfigurationPanel_noPreview"));
|
||||
noPreview.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
noPreview.setVerticalAlignment(SwingConstants.CENTER);
|
||||
|
||||
preview = createVideoContainer(noPreview);
|
||||
Dimension previewSize = new Dimension(150, 150);
|
||||
preview.setMaximumSize(previewSize);
|
||||
preview.setMinimumSize(previewSize);
|
||||
preview.setPreferredSize(previewSize);
|
||||
|
||||
comboBoxListener = new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
Object selection = comboBox.getSelectedItem();
|
||||
CaptureDeviceInfo device = null;
|
||||
if (selection instanceof DeviceConfigurationComboBoxModel.CaptureDevice)
|
||||
{
|
||||
device =
|
||||
((DeviceConfigurationComboBoxModel.CaptureDevice) selection).info;
|
||||
}
|
||||
|
||||
createPreview(device, preview);
|
||||
}
|
||||
};
|
||||
comboBox.addActionListener(comboBoxListener);
|
||||
} else
|
||||
preview = null;
|
||||
|
||||
Container deviceContainer = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints deviceConstraints = new GridBagConstraints();
|
||||
deviceConstraints.anchor = GridBagConstraints.NORTHWEST;
|
||||
deviceConstraints.gridx = 0;
|
||||
deviceConstraints.gridy = 0;
|
||||
deviceConstraints.weightx = 0;
|
||||
deviceContainer.add(label, deviceConstraints);
|
||||
deviceConstraints.gridx = 1;
|
||||
deviceConstraints.weightx = 1;
|
||||
deviceContainer.add(comboBox, deviceConstraints);
|
||||
if (preview != null)
|
||||
{
|
||||
deviceConstraints.gridx = 2;
|
||||
deviceConstraints.weightx = 0;
|
||||
deviceContainer.add(preview, deviceConstraints);
|
||||
}
|
||||
|
||||
comboBox.setModel(new DeviceConfigurationComboBoxModel(mediaService
|
||||
.getDeviceConfiguration(), type));
|
||||
if (comboBoxListener != null)
|
||||
comboBoxListener.actionPerformed(null);
|
||||
|
||||
Container container = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.weightx = 1;
|
||||
constraints.weighty = 0;
|
||||
container.add(deviceContainer, constraints);
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
constraints.gridy = 1;
|
||||
constraints.weighty = 1;
|
||||
container.add(createEncodingControls(type), constraints);
|
||||
return container;
|
||||
}
|
||||
|
||||
private Component createEncodingControls(int type)
|
||||
{
|
||||
ResourceManagementService resources = MediaActivator.getResources();
|
||||
String key;
|
||||
|
||||
final JTable table = new JTable();
|
||||
table.setFillsViewportHeight(true);
|
||||
table.setShowGrid(false);
|
||||
table.setTableHeader(null);
|
||||
|
||||
key = "MediaConfigurationPanel_encodings";
|
||||
JLabel label = new JLabel(resources.getI18NString(key));
|
||||
label.setDisplayedMnemonic(resources.getI18nMnemonic(key));
|
||||
label.setLabelFor(table);
|
||||
|
||||
key = "MediaConfigurationPanel_up";
|
||||
final JButton upButton = new JButton(resources.getI18NString(key));
|
||||
upButton.setMnemonic(resources.getI18nMnemonic(key));
|
||||
|
||||
key = "MediaConfigurationPanel_down";
|
||||
final JButton downButton = new JButton(resources.getI18NString(key));
|
||||
downButton.setMnemonic(resources.getI18nMnemonic(key));
|
||||
|
||||
Container buttonBar = new JPanel(new GridLayout(0, 1));
|
||||
buttonBar.add(upButton);
|
||||
buttonBar.add(downButton);
|
||||
|
||||
Container container = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints constraints = new GridBagConstraints();
|
||||
constraints.anchor = GridBagConstraints.NORTHWEST;
|
||||
constraints.fill = GridBagConstraints.HORIZONTAL;
|
||||
constraints.gridwidth = 2;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 0;
|
||||
constraints.weightx = 0;
|
||||
constraints.weighty = 0;
|
||||
container.add(label, constraints);
|
||||
constraints.anchor = GridBagConstraints.CENTER;
|
||||
constraints.fill = GridBagConstraints.BOTH;
|
||||
constraints.gridwidth = 1;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridy = 1;
|
||||
constraints.weightx = 1;
|
||||
constraints.weighty = 1;
|
||||
container.add(new JScrollPane(table), constraints);
|
||||
constraints.anchor = GridBagConstraints.NORTHEAST;
|
||||
constraints.fill = GridBagConstraints.NONE;
|
||||
constraints.gridwidth = 1;
|
||||
constraints.gridx = 1;
|
||||
constraints.gridy = 1;
|
||||
constraints.weightx = 0;
|
||||
constraints.weighty = 0;
|
||||
container.add(buttonBar, constraints);
|
||||
|
||||
table.setModel(new EncodingConfigurationTableModel(mediaService
|
||||
.getEncodingConfiguration(), type));
|
||||
|
||||
/*
|
||||
* The first column contains the check boxes which enable/disable their
|
||||
* associated encodings and it doesn't make sense to make it wider than
|
||||
* the check boxes.
|
||||
*/
|
||||
TableColumnModel tableColumnModel = table.getColumnModel();
|
||||
TableColumn tableColumn = tableColumnModel.getColumn(0);
|
||||
tableColumn.setMaxWidth(tableColumn.getMinWidth());
|
||||
|
||||
ListSelectionListener tableSelectionListener =
|
||||
new ListSelectionListener()
|
||||
{
|
||||
public void valueChanged(ListSelectionEvent event)
|
||||
{
|
||||
if (table.getSelectedRowCount() == 1)
|
||||
{
|
||||
int selectedRow = table.getSelectedRow();
|
||||
if (selectedRow > -1)
|
||||
{
|
||||
upButton.setEnabled(selectedRow > 0);
|
||||
downButton.setEnabled(selectedRow < (table
|
||||
.getRowCount() - 1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
upButton.setEnabled(false);
|
||||
downButton.setEnabled(false);
|
||||
}
|
||||
};
|
||||
table.getSelectionModel().addListSelectionListener(
|
||||
tableSelectionListener);
|
||||
tableSelectionListener.valueChanged(null);
|
||||
|
||||
ActionListener buttonListener = new ActionListener()
|
||||
{
|
||||
public void actionPerformed(ActionEvent event)
|
||||
{
|
||||
Object source = event.getSource();
|
||||
boolean up;
|
||||
if (source == upButton)
|
||||
up = true;
|
||||
else if (source == downButton)
|
||||
up = false;
|
||||
else
|
||||
return;
|
||||
|
||||
((EncodingConfigurationTableModel) table.getModel()).move(table
|
||||
.getSelectedRow(), up);
|
||||
}
|
||||
};
|
||||
upButton.addActionListener(buttonListener);
|
||||
downButton.addActionListener(buttonListener);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
private void createPreview(CaptureDeviceInfo device,
|
||||
final Container videoContainer)
|
||||
{
|
||||
videoContainer.removeAll();
|
||||
|
||||
if (device == null)
|
||||
return;
|
||||
|
||||
Player player = null;
|
||||
Exception exception = null;
|
||||
try
|
||||
{
|
||||
player = Manager.createPlayer(device.getLocator());
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
catch (NoPlayerException ex)
|
||||
{
|
||||
exception = ex;
|
||||
}
|
||||
if (exception != null)
|
||||
{
|
||||
logger.error("Failed to create preview for device " + device,
|
||||
exception);
|
||||
return;
|
||||
}
|
||||
|
||||
player.addControllerListener(new ControllerListener()
|
||||
{
|
||||
public void controllerUpdate(ControllerEvent event)
|
||||
{
|
||||
controllerUpdateForPreview(event, videoContainer);
|
||||
}
|
||||
});
|
||||
player.start();
|
||||
}
|
||||
|
||||
private JComponent createVideoContainer(Component noVideoComponent)
|
||||
{
|
||||
return new VideoContainer(noVideoComponent);
|
||||
}
|
||||
|
||||
private void disposePlayer(Player player)
|
||||
{
|
||||
player.stop();
|
||||
player.deallocate();
|
||||
player.close();
|
||||
}
|
||||
|
||||
private char getDisplayedMnemonic(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DeviceConfigurationComboBoxModel.AUDIO:
|
||||
return MediaActivator.getResources().getI18nMnemonic(
|
||||
"MediaConfigurationPanel_audio");
|
||||
case DeviceConfigurationComboBoxModel.VIDEO:
|
||||
return MediaActivator.getResources().getI18nMnemonic(
|
||||
"MediaConfigurationPanel_video");
|
||||
default:
|
||||
throw new IllegalArgumentException("type");
|
||||
}
|
||||
}
|
||||
|
||||
private String getLabelText(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DeviceConfigurationComboBoxModel.AUDIO:
|
||||
return MediaActivator.getResources().getI18NString(
|
||||
"MediaConfigurationPanel_audio");
|
||||
case DeviceConfigurationComboBoxModel.VIDEO:
|
||||
return MediaActivator.getResources().getI18NString(
|
||||
"MediaConfigurationPanel_video");
|
||||
default:
|
||||
throw new IllegalArgumentException("type");
|
||||
}
|
||||
}
|
||||
|
||||
private void showPreview(final Container previewContainer,
|
||||
final Component preview, final Player player)
|
||||
{
|
||||
if (!SwingUtilities.isEventDispatchThread())
|
||||
{
|
||||
SwingUtilities.invokeLater(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
showPreview(previewContainer, preview, player);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
previewContainer.removeAll();
|
||||
|
||||
if (preview != null)
|
||||
{
|
||||
HierarchyListener hierarchyListener = new HierarchyListener()
|
||||
{
|
||||
private Window window;
|
||||
|
||||
private WindowListener windowListener;
|
||||
|
||||
public void dispose()
|
||||
{
|
||||
if (windowListener != null)
|
||||
{
|
||||
if (window != null)
|
||||
{
|
||||
window.removeWindowListener(windowListener);
|
||||
window = null;
|
||||
}
|
||||
windowListener = null;
|
||||
}
|
||||
|
||||
preview.removeHierarchyListener(this);
|
||||
|
||||
disposePlayer(player);
|
||||
}
|
||||
|
||||
public void hierarchyChanged(HierarchyEvent event)
|
||||
{
|
||||
if ((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
|
||||
{
|
||||
if (preview.isDisplayable())
|
||||
{
|
||||
if (windowListener == null)
|
||||
{
|
||||
window =
|
||||
SwingUtilities.windowForComponent(preview);
|
||||
if (window != null)
|
||||
{
|
||||
windowListener = new WindowAdapter()
|
||||
{
|
||||
public void windowClosing(
|
||||
WindowEvent event)
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
};
|
||||
window.addWindowListener(windowListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
preview.addHierarchyListener(hierarchyListener);
|
||||
|
||||
previewContainer.add(preview);
|
||||
}
|
||||
else
|
||||
disposePlayer(player);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.swing;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Lubomir Marinov
|
||||
*/
|
||||
public class VideoContainer
|
||||
extends JPanel
|
||||
{
|
||||
private final ContainerListener containerListener = new ContainerListener()
|
||||
{
|
||||
|
||||
/*
|
||||
* Since the videoContainer displays either noVideoComponent or a single
|
||||
* visual Component which represents video, ensures the last Component
|
||||
* added to the Container is the only Component it contains i.e.
|
||||
* noVideoComponent goes away when the video is displayed and the video
|
||||
* goes away when noVideoComponent is displayed.
|
||||
*/
|
||||
public void componentAdded(ContainerEvent event)
|
||||
{
|
||||
Container container = event.getContainer();
|
||||
Component local = ((VideoLayout) container.getLayout()).getLocal();
|
||||
Component added = event.getChild();
|
||||
|
||||
if ((local != null) && (added == local))
|
||||
return;
|
||||
|
||||
Component[] components = container.getComponents();
|
||||
boolean validate = false;
|
||||
|
||||
for (int i = 0; i < components.length; i++)
|
||||
{
|
||||
Component component = components[i];
|
||||
|
||||
if ((component != added) && (component != local))
|
||||
{
|
||||
container.remove(component);
|
||||
validate = true;
|
||||
}
|
||||
}
|
||||
if (validate)
|
||||
container.validate();
|
||||
};
|
||||
|
||||
/*
|
||||
* Displays noVideoComponent when there is no visual Component which
|
||||
* represents video to be displayed.
|
||||
*/
|
||||
public void componentRemoved(ContainerEvent event)
|
||||
{
|
||||
Container container = event.getContainer();
|
||||
|
||||
if ((container.getComponentCount() <= 0)
|
||||
|| (((VideoLayout) container.getLayout()).getRemote() == null))
|
||||
{
|
||||
container.add(noVideoComponent, VideoLayout.REMOTE);
|
||||
container.validate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final Component noVideoComponent;
|
||||
|
||||
public VideoContainer(Component noVideoComponent)
|
||||
{
|
||||
super(new VideoLayout());
|
||||
|
||||
this.noVideoComponent = noVideoComponent;
|
||||
|
||||
addContainerListener(containerListener);
|
||||
add(noVideoComponent, VideoLayout.REMOTE);
|
||||
}
|
||||
|
||||
public Component add(Component comp)
|
||||
{
|
||||
add(comp, VideoLayout.REMOTE);
|
||||
return comp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensures noVideoComponent is displayed even when the clients of the
|
||||
* videoContainer invoke its #removeAll() to remove their previous visual
|
||||
* Components representing video. Just adding noVideoComponent upon
|
||||
* ContainerEvent#COMPONENT_REMOVED when there is no other Component left in
|
||||
* the Container will cause an infinite loop because Container#removeAll()
|
||||
* will detect that a new Component has been added while dispatching the
|
||||
* event and will then try to remove the new Component.
|
||||
*/
|
||||
public void removeAll()
|
||||
{
|
||||
removeContainerListener(containerListener);
|
||||
try
|
||||
{
|
||||
super.removeAll();
|
||||
}
|
||||
finally
|
||||
{
|
||||
addContainerListener(containerListener);
|
||||
containerListener.componentRemoved(new ContainerEvent(this,
|
||||
ContainerEvent.COMPONENT_REMOVED, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
Bundle-Name: Swing Common
|
||||
Bundle-Description: Common/generic Swing additions not specific to SIP Communicator
|
||||
Bundle-Vendor: sip-communicator.org
|
||||
Bundle-Version: 0.0.1
|
||||
Import-Package: javax.swing
|
||||
Export-Package: net.java.sip.communicator.swing
|
||||
Loading…
Reference in new issue