package BlobUI;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;
import javax.media.CaptureDeviceInfo;
import javax.media.CaptureDeviceManager;
import javax.media.Format;
import javax.media.MediaLocator;
import javax.media.format.VideoFormat;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import UI.VideoEffectUIFactory;
import VideoProcessing.RgbVideoEffect;
import Blob.BlobPublishingCamera;
import Blob.FourNeighborBlobDetector;
public class BlobPublishingCameraPanel extends JPanel {
/** Serialization id. */
private static final long serialVersionUID = 1789835098650851831L;
/** The {@link BlobPublishingCamera} that this JPanel interacts with. */
private BlobPublishingCamera camera;
/** Index of the effect chain element being watched. */
private int curFeedIndex;
// private JComboBox cmbEffect;
private JRadioButton btnVideoInput[];
private BlobVideoPanel pnlVideo;
public BlobPublishingCameraPanel(BlobPublishingCamera camera) {
if (camera == null) {
throw new NullPointerException("camera");
}
if (camera.getProcessingChain() == null) {
throw new IllegalStateException(
"Camera must already be opened before UI may be created.");
}
// Register our effects' UIs
VideoEffectUIFactory.getInstance().registerClass(
FourNeighborBlobDetector.class,
FourNeighborBlobDetectorPanel.class);
//
this.camera = camera;
createUI();
}
public BlobPublishingCameraPanel(String path) {
camera = new BlobPublishingCamera();
if (path.equalsIgnoreCase("webcam")) {
listDevices();
if (autoOpen()) {
initProcessingChain();
this.setSize(800, 600);
createUI();
} else {
JOptionPane.showMessageDialog(this, "Unable to open webcam");
}
} else {
if (openVideoURL(path, "file:")) {
initProcessingChain();
this.setSize(800, 600);
createUI();
} else {
JOptionPane.showMessageDialog(this, "Unable to open video");
}
}
}
private boolean autoOpen() {
boolean success = false;
int camNum = 0;
String mediaLoc;
do {
mediaLoc = "vfw://" + camNum;
System.out.println("Trying video for windows, camera #" + camNum
+ ": " + mediaLoc);
success = openVideoURL(mediaLoc, "");
} while (!success && (++camNum) < 4);
return success;
}
private void listDevices() {
Vector deviceInfos = CaptureDeviceManager
.getDeviceList(new VideoFormat("RGB"));
if (deviceInfos.isEmpty()) {
System.out.println("No capture devices found.");
} else {
for (Object o : deviceInfos) {
CaptureDeviceInfo info = (CaptureDeviceInfo) o;
System.out.println(info.getName() + " :");
for (Format format : info.getFormats()) {
System.out
.println(String.format("\t%s", format.toString()));
}
}
}
}
public boolean isProcessing() {
return camera == null ? false : true;
}
private void initProcessingChain() {
if (camera == null) {
throw new NullPointerException("camera");
}
if (camera.getProcessingChain() == null) {
throw new IllegalStateException(
"Camera must already be opened before UI may be created.");
}
VideoEffectUIFactory.getInstance().registerClass(
FourNeighborBlobDetector.class,
FourNeighborBlobDetectorPanel.class);
}
private boolean openVideoURL(String path, String type) {
MediaLocator ml;
if ((ml = new MediaLocator(type + "" + path)) == null) {
return false;
}
return camera.open(ml);
}
public void closeCameraPanel() {
if (camera != null) {
camera.close();
this.switchFeed(0);
}
}
private void createUI() {
// Display the visual & control component if there's one.
setLayout(new BorderLayout());
// ////// Left
JPanel pnlLeft = new JPanel();
pnlLeft.setLayout(new BorderLayout());
pnlVideo = new BlobVideoPanel(camera);
pnlLeft.add("Center", pnlVideo);
/*
* JCheckBox chkFlip = new JCheckBox("Flip video vertically");
* chkFlip.addItemListener(new ItemListener() { public void
* itemStateChanged(ItemEvent e) {
* pnlVideo.setFlipVideo(e.getStateChange() == ItemEvent.SELECTED); }
* }); pnlLeft.add("South", chkFlip);
*/
add("Center", pnlLeft);
// ////// Right
JPanel pnlRight = new JPanel();
GridBagLayout gbLayout = new GridBagLayout();
pnlRight.setLayout(gbLayout);
ButtonGroup btngrpInput = new ButtonGroup();
btnVideoInput = new JRadioButton[camera.getProcessingChain().length];
JPanel pnlInput = new JPanel();
pnlInput.setBorder(new TitledBorder(new EtchedBorder(), "Video View"));
GridLayout inputLayout = new GridLayout(0, 1); // camera.getProcessingChain().length);
pnlInput.setLayout(inputLayout);
for (int i = 0; i < camera.getProcessingChain().length; i++) {
btnVideoInput[i] = new JRadioButton(Integer.toString(i + 1) + " "
+ camera.getProcessingChain()[i].getName());
btngrpInput.add(btnVideoInput[i]);
pnlInput.add(btnVideoInput[i]);
final int index = i;
btnVideoInput[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// if (btnVideoInput[index])
switchFeed(index); // effectIndex);
}
});
}
GridBagConstraints constr = new GridBagConstraints();
constr.gridwidth = 1;
constr.gridheight = 1;
constr.fill = GridBagConstraints.BOTH;
constr.anchor = GridBagConstraints.NORTH;
constr.gridwidth = GridBagConstraints.REMAINDER; // end row
gbLayout.setConstraints(pnlInput, constr);
pnlRight.add(pnlInput);
// add(pnlInput, "South");
// // Processing Chain UI
// pnlRight.setLayout(new B)
int i = 0;
for (RgbVideoEffect effect : camera.getProcessingChain()) {
// effect.createUI(pnl);
JPanel ui = VideoEffectUIFactory.getInstance().provideFor(effect);
if (ui != null) {
JPanel pnl = new JPanel();
pnl.setBorder(new TitledBorder(new EtchedBorder(), effect
.getName()));
pnl.add(ui);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridwidth = GridBagConstraints.REMAINDER; // end row
gbLayout.setConstraints(pnl, gbc);
pnlRight.add(pnl);
pnl.addMouseListener(new EffectPanelMouseListener(i));
}
i++;
}
add("West", pnlRight);
}
public void addNotify() {
super.addNotify();
// pack();
this.getParent().validate();
}
/*
* @Override public void itemStateChanged(ItemEvent e) { if(e.getSource() ==
* cmbEffect) { int effectIndex = Integer.parseInt(
* ((String)e.getItem()).substring(0, 2).trim()) - 1; if(e.getStateChange()
* == ItemEvent.DESELECTED) {
* //camera.getProcessingChain()[effectIndex].removeVideoFrameListener
* (this); } else if(e.getStateChange() == ItemEvent.SELECTED) {
* switchFeed(effectIndex); } } }
*/
/**
* Switches the video input to an effect in the camera's processing chain.
*
* @param index
* Index into the processing chain.
*/
public void switchFeed(int index) {
if (camera.getBlobManager().getVideoSize().width > 0) {
pnlVideo.setInput(camera.getProcessingChain()[index]);
curFeedIndex = index;
}
}
/**
* Listens to mouse events.
*/
private class EffectPanelMouseListener implements MouseListener {
private int effectIndex;
public EffectPanelMouseListener(int effectIndex) {
this.effectIndex = effectIndex;
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1) {
switchFeed(effectIndex);
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
}
}