コード例 #1
1
  /** Initializes contained components. */
  private void initComponents() {
    final SimpleDateFormat format = new SimpleDateFormat("mm:ss");
    final Calendar c = Calendar.getInstance();
    final JLabel counter = new JLabel();

    counter.setForeground(Color.red);
    counter.setFont(counter.getFont().deriveFont((float) (counter.getFont().getSize() + 5)));

    setLayout(new GridBagLayout());
    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));

    GridBagConstraints constraints = new GridBagConstraints();

    JLabel messageLabel =
        new JLabel(
            GuiActivator.getResources().getI18NString("service.gui.security.SECURITY_ALERT"));

    messageLabel.setForeground(Color.WHITE);

    constraints.anchor = GridBagConstraints.CENTER;
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 0;
    add(messageLabel, constraints);

    constraints.anchor = GridBagConstraints.CENTER;
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 1;
    add(counter, constraints);

    ZrtpControl zrtpControl = null;
    if (securityControl instanceof ZrtpControl) zrtpControl = (ZrtpControl) securityControl;

    long initialSeconds = 0;

    if (zrtpControl != null) initialSeconds = zrtpControl.getTimeoutValue();

    c.setTimeInMillis(initialSeconds);

    counter.setText(format.format(c.getTime()));

    if (initialSeconds > 0)
      timer.schedule(
          new TimerTask() {
            @Override
            public void run() {
              if (c.getTimeInMillis() - 1000 > 0) {
                c.add(Calendar.SECOND, -1);
                counter.setText(format.format(c.getTime()));
              }
            }
          },
          1000,
          1000);
  }
コード例 #2
0
  /**
   * Creates the buttons panel.
   *
   * @return the buttons panel
   */
  private Component createButtonsPanel() {
    JPanel buttonsPanel = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));

    JButton okButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.OK"));

    okButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = (MediaDevice) deviceComboBox.getSelectedItem();

            dispose();
          }
        });

    buttonsPanel.add(okButton);

    cancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = null;
            dispose();
          }
        });

    buttonsPanel.add(cancelButton);

    return buttonsPanel;
  }
コード例 #3
0
  /**
   * The handler for the security event received. The security event for starting establish a secure
   * connection.
   *
   * @param evt the security started event received
   */
  public void securityNegotiationStarted(CallPeerSecurityNegotiationStartedEvent evt) {
    if (Boolean.parseBoolean(
        GuiActivator.getResources().getSettingsString("impl.gui.PARANOIA_UI"))) {
      SrtpControl srtpControl = null;
      if (callPeer instanceof MediaAwareCallPeer) srtpControl = evt.getSecurityController();

      securityPanel = new ParanoiaTimerSecurityPanel<SrtpControl>(srtpControl);

      setSecurityPanelVisible(true);
    }
  }
コード例 #4
0
  /**
   * Creates preview for the device(video) in the video container.
   *
   * @param device the device
   * @param videoContainer the container
   * @throws IOException a problem accessing the device.
   * @throws MediaException a problem getting preview.
   */
  private static void createPreview(MediaDevice device, final JComponent videoContainer)
      throws IOException, MediaException {
    videoContainer.removeAll();

    videoContainer.revalidate();
    videoContainer.repaint();

    if (device == null) return;

    Component c =
        (Component)
            GuiActivator.getMediaService()
                .getVideoPreviewComponent(
                    device, videoContainer.getSize().width, videoContainer.getSize().height);

    videoContainer.add(c);
  }
コード例 #5
0
ファイル: RecordButton.java プロジェクト: 0xbb/jitsi
  /**
   * Creates a full filename for the call by combining the directory, file prefix and extension. If
   * the directory is <tt>null</tt> user's home directory is used.
   *
   * @param savedCallsPath the path to the directory in which the generated file name is to be
   *     placed
   * @return a full filename for the call
   */
  private String createDefaultFilename(String savedCallsPath) {
    // set to user's home when null
    if (savedCallsPath == null) {
      try {
        savedCallsPath =
            GuiActivator.getFileAccessService().getDefaultDownloadDirectory().getAbsolutePath();
      } catch (IOException ioex) {
        // Leave it in the current directory.
      }
    }

    String ext = configuration.getString(Recorder.FORMAT);

    // Use a default format when the configured one seems invalid.
    if ((ext == null) || (ext.length() == 0) || !isSupportedFormat(ext))
      ext = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
    return ((savedCallsPath == null) ? "" : (savedCallsPath + File.separator))
        + generateCallFilename(ext);
  }
コード例 #6
0
  /**
   * Set the image of the peer
   *
   * @param image new image
   */
  public void setPeerImage(byte[] image) {
    // If the image is still null we try to obtain it from one of the
    // available contact sources.
    if (image == null || image.length <= 0) {
      GuiActivator.getContactList().setSourceContactImage(peerName, photoLabel, 100, 100);
    } else {
      peerImage = ImageUtils.getScaledRoundedIcon(image, 100, 100);
      if (peerImage == null) peerImage = getPhotoLabelIcon();

      if (!SwingUtilities.isEventDispatchThread()) {
        SwingUtilities.invokeLater(
            new Runnable() {
              public void run() {
                photoLabel.setIcon(peerImage);
                photoLabel.repaint();
              }
            });
      } else {
        photoLabel.setIcon(peerImage);
        photoLabel.repaint();
      }
    }
  }
コード例 #7
0
  /**
   * Volume control used by the button.
   *
   * @return volume control used by the button.
   */
  private VolumeControl getVolumeControl() {
    VolumeControl volumeControl = GuiActivator.getMediaService().getInputVolumeControl();

    volumeControl.addVolumeChangeListener(this);
    return volumeControl;
  }
コード例 #8
0
  /**
   * Indicates that the security is turned on.
   *
   * <p>Sets the secured status icon to the status panel and initializes/updates the corresponding
   * security details.
   *
   * @param evt Details about the event that caused this message.
   */
  public void securityOn(final CallPeerSecurityOnEvent evt) {
    if (!SwingUtilities.isEventDispatchThread()) {
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              securityOn(evt);
            }
          });
      return;
    }

    // If the securityOn is called without a specific event, we'll just set
    // the security label status to on.
    if (evt == null) {
      securityStatusLabel.setSecurityOn();
      return;
    }

    SrtpControl srtpControl = evt.getSecurityController();

    if (!srtpControl.requiresSecureSignalingTransport()
        || callPeer.getProtocolProvider().isSignalingTransportSecure()) {
      if (srtpControl instanceof ZrtpControl) {
        securityStatusLabel.setText("zrtp");

        if (!((ZrtpControl) srtpControl).isSecurityVerified())
          securityStatusLabel.setSecurityPending();
        else securityStatusLabel.setSecurityOn();
      } else securityStatusLabel.setSecurityOn();
    }

    // if we have some other panel, using other control
    if (!srtpControl.getClass().isInstance(securityPanel.getSecurityControl())
        || (securityPanel instanceof ParanoiaTimerSecurityPanel)) {
      setSecurityPanelVisible(false);

      securityPanel = SecurityPanel.create(this, callPeer, srtpControl);

      if (srtpControl instanceof ZrtpControl)
        ((ZrtpSecurityPanel) securityPanel).setSecurityStatusLabel(securityStatusLabel);
    }

    securityPanel.securityOn(evt);

    boolean isSecurityLowPriority =
        Boolean.parseBoolean(
            GuiActivator.getResources()
                .getSettingsString("impl.gui.I_DONT_CARE_THAT_MUCH_ABOUT_SECURITY"));

    // Display ZRTP panel in case SAS was not verified or a AOR mismtach
    // was detected during creation of ZrtpSecurityPanel.
    // Don't show panel if user does not care about security at all.
    if (srtpControl instanceof ZrtpControl
        && !isSecurityLowPriority
        && (!((ZrtpControl) srtpControl).isSecurityVerified()
            || ((ZrtpSecurityPanel) securityPanel).isZidAorMismatch())) {
      setSecurityPanelVisible(true);
    }

    this.revalidate();
  }
コード例 #9
0
  /** Creates sound level related components. */
  private void createSoundLevelIndicators() {
    TransparentPanel localLevelPanel = new TransparentPanel(new BorderLayout(5, 0));
    TransparentPanel remoteLevelPanel = new TransparentPanel(new BorderLayout(5, 0));

    localLevel =
        new InputVolumeControlButton(
            call, ImageLoader.MICROPHONE, ImageLoader.MUTE_BUTTON, false, false);
    remoteLevel =
        new OutputVolumeControlButton(call.getConference(), ImageLoader.HEADPHONE, false, false)
            .getComponent();

    final SoundLevelIndicator localLevelIndicator =
        new SoundLevelIndicator(SoundLevelChangeEvent.MIN_LEVEL, SoundLevelChangeEvent.MAX_LEVEL);
    final SoundLevelIndicator remoteLevelIndicator =
        new SoundLevelIndicator(SoundLevelChangeEvent.MIN_LEVEL, SoundLevelChangeEvent.MAX_LEVEL);

    localLevelPanel.add(localLevel, BorderLayout.WEST);
    localLevelPanel.add(localLevelIndicator, BorderLayout.CENTER);
    remoteLevelPanel.add(remoteLevel, BorderLayout.WEST);
    remoteLevelPanel.add(remoteLevelIndicator, BorderLayout.CENTER);

    GridBagConstraints constraints = new GridBagConstraints();
    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 5;
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.insets = new Insets(10, 0, 0, 0);

    add(localLevelPanel, constraints);

    constraints.fill = GridBagConstraints.NONE;
    constraints.gridx = 0;
    constraints.gridy = 6;
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.insets = new Insets(5, 0, 10, 0);

    add(remoteLevelPanel, constraints);

    if (!GuiActivator.getConfigurationService()
        .getBoolean(
            "net.java.sip.communicator.impl.gui.main.call." + "DISABLE_SOUND_LEVEL_INDICATORS",
            false)) {
      callPeer.addStreamSoundLevelListener(
          new SoundLevelListener() {
            public void soundLevelChanged(Object source, int level) {
              remoteLevelIndicator.updateSoundLevel(level);
            }
          });
      /*
       * By the time the UI gets to be initialized, the callPeer may have
       * been removed from its Call. As far as the UI is concerned, the
       * callPeer will never have a Call again and there will be no audio
       * levels to display anyway so there is no point in throwing a
       * NullPointerException here.
       */
      if (call != null) {
        call.addLocalUserSoundLevelListener(
            new SoundLevelListener() {
              public void soundLevelChanged(Object source, int level) {
                localLevelIndicator.updateSoundLevel(level);
              }
            });
      }
    }
  }
コード例 #10
0
ファイル: RecordButton.java プロジェクト: 0xbb/jitsi
/**
 * The button that starts/stops the call recording.
 *
 * @author Dmitri Melnikov
 * @author Lubomir Marinov
 */
public class RecordButton extends AbstractCallToggleButton {
  /** The logger used by the <tt>RecordButton</tt> class and its instances for logging output. */
  private static final Logger logger = Logger.getLogger(RecordButton.class);

  /** The date format used in file names. */
  private static final SimpleDateFormat FORMAT = new SimpleDateFormat("*****@*****.**");

  /** Configuration service. */
  private static final ConfigurationService configuration = GuiActivator.getConfigurationService();

  /** Resource service. */
  private static final ResourceManagementService resources = GuiActivator.getResources();

  /** Maximum allowed file name length. */
  private static final int MAX_FILENAME_LENGTH = 64;

  /** The full filename of the saved call on the file system. */
  private String callFilename;

  /** Call file chooser. */
  private SipCommFileChooser callFileChooser;

  /**
   * The <tt>Recorder</tt> which is depicted by this <tt>RecordButton</tt> and which is to record or
   * records {@link #call} into {@link #callFilename}.
   */
  private Recorder recorder;

  /**
   * Initializes a new <tt>RecordButton</tt> instance which is to record the audio stream.
   *
   * @param call the <tt>Call</tt> to be associated with the new instance and to have the audio
   *     stream recorded
   */
  public RecordButton(Call call) {
    this(call, false);
  }

  /**
   * Initializes a new <tt>RecordButton</tt> instance which is to record the audio stream.
   *
   * @param call the <tt>Call</tt> to be associated with the new instance and to have its audio
   *     stream recorded
   * @param selected <tt>true</tt> if the new toggle button is to be initially selected; otherwise,
   *     <tt>false</tt>
   */
  public RecordButton(Call call, boolean selected) {
    super(call, true, selected, ImageLoader.RECORD_BUTTON, ImageLoader.RECORD_BUTTON_PRESSED, null);

    String toolTip = resources.getI18NString("service.gui.RECORD_BUTTON_TOOL_TIP");
    String saveDir = configuration.getString(Recorder.SAVED_CALLS_PATH);

    if ((saveDir != null) && (saveDir.length() != 0)) toolTip += " (" + saveDir + ")";
    setToolTipText(toolTip);
  }

  /** Starts/stops the recording of the call when this button is pressed. */
  @Override
  public void buttonPressed() {
    if (call != null) {
      // start recording
      if (isSelected()) {
        boolean startedRecording = false;

        try {
          startedRecording = startRecording();
        } finally {
          if (!startedRecording && (recorder != null)) {
            try {
              recorder.stop();
            } finally {
              recorder = null;
            }
          }
          setSelected(startedRecording);
        }
      }
      // stop recording
      else if (recorder != null) {
        try {
          recorder.stop();
        } finally {
          recorder = null;
          setSelected(false);
        }
      }
    }
  }

  /**
   * Creates a full filename for the call by combining the directory, file prefix and extension. If
   * the directory is <tt>null</tt> user's home directory is used.
   *
   * @param savedCallsPath the path to the directory in which the generated file name is to be
   *     placed
   * @return a full filename for the call
   */
  private String createDefaultFilename(String savedCallsPath) {
    // set to user's home when null
    if (savedCallsPath == null) {
      try {
        savedCallsPath =
            GuiActivator.getFileAccessService().getDefaultDownloadDirectory().getAbsolutePath();
      } catch (IOException ioex) {
        // Leave it in the current directory.
      }
    }

    String ext = configuration.getString(Recorder.FORMAT);

    // Use a default format when the configured one seems invalid.
    if ((ext == null) || (ext.length() == 0) || !isSupportedFormat(ext))
      ext = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;
    return ((savedCallsPath == null) ? "" : (savedCallsPath + File.separator))
        + generateCallFilename(ext);
  }

  /**
   * Generates a file name for the call based on the current date and the names of the peers in the
   * call.
   *
   * @param ext file extension
   * @return the file name for the call
   */
  private String generateCallFilename(String ext) {
    String filename = FORMAT.format(new Date()) + "-call";
    int maxLength = MAX_FILENAME_LENGTH - 2 - filename.length() - ext.length();
    String peerName = getCallPeerName(maxLength);
    filename += ((!peerName.equals("")) ? "-" : "") + peerName + "." + ext;
    return filename;
  }

  /**
   * Gets and formats the names of the peers in the call.
   *
   * @param maxLength maximum length of the filename
   * @return the name of the peer in the call formated
   */
  private String getCallPeerName(int maxLength) {
    List<CallPeer> callPeers = call.getConference().getCallPeers();
    CallPeer callPeer = null;
    String peerName = "";
    if (!callPeers.isEmpty()) {
      callPeer = callPeers.get(0);
      if (callPeer != null) {
        peerName = callPeer.getDisplayName();
        peerName = peerName.replaceAll("[^\\da-zA-Z\\_\\-@\\.]", "");
        if (peerName.length() > maxLength) {
          peerName = peerName.substring(0, maxLength);
        }
      }
    }
    return peerName;
  }

  /**
   * Gets the <tt>Recorder</tt> represented by this <tt>RecordButton</tt> creating it first if it
   * does not exist.
   *
   * @return the <tt>Recorder</tt> represented by this <tt>RecordButton</tt> created first if it
   *     does not exist
   * @throws OperationFailedException if anything goes wrong while creating the <tt>Recorder</tt> to
   *     be represented by this <tt>RecordButton</tt>
   */
  private Recorder getRecorder() throws OperationFailedException {
    if (recorder == null) {
      OperationSetBasicTelephony<?> telephony =
          call.getProtocolProvider().getOperationSet(OperationSetBasicTelephony.class);

      recorder = telephony.createRecorder(call);
    }
    return recorder;
  }

  /**
   * Determines whether the extension of a specific <tt>File</tt> specifies a format supported by
   * the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>.
   *
   * @param file the <tt>File</tt> whose extension is to be checked whether it specifies a format
   *     supported by the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>
   * @return <tt>true</tt> if the extension of the specified <tt>file</tt> specifies a format
   *     supported by the <tt>Recorder</tt> represented by this <tt>RecordButton</tt>; otherwise,
   *     <tt>false</tt>
   */
  private boolean isSupportedFormat(File file) {
    String extension = SoundFileUtils.getExtension(file);

    return (extension != null) && (extension.length() != 0) && isSupportedFormat(extension);
  }

  /**
   * Determines whether a specific format is supported by the <tt>Recorder</tt> represented by this
   * <tt>RecordButton</tt>.
   *
   * @param format the format which is to be checked whether it is supported by the
   *     <tt>Recorder</tt> represented by this <tt>RecordButton</tt>
   * @return <tt>true</tt> if the specified <tt>format</tt> is supported by the <tt>Recorder</tt>
   *     represented by this <tt>RecordButton</tt>; otherwise, <tt>false</tt>
   */
  private boolean isSupportedFormat(String format) {
    Recorder recorder;

    try {
      recorder = getRecorder();
    } catch (OperationFailedException ofex) {
      logger.error("Failed to get Recorder", ofex);
      return false;
    }

    List<String> supportedFormats = recorder.getSupportedFormats();

    return (supportedFormats != null) && supportedFormats.contains(format);
  }

  /**
   * Starts recording {@link #call} creating {@link #recorder} first and asking the user for the
   * recording format and file if they are not configured in the "Call Recording" configuration
   * form.
   *
   * @return <tt>true</tt> if the recording has been started successfully; otherwise, <tt>false</tt>
   */
  private boolean startRecording() {
    String savedCallsPath = configuration.getString(Recorder.SAVED_CALLS_PATH);
    String callFormat;

    // Ask the user where to save the call.
    if ((savedCallsPath == null) || (savedCallsPath.length() == 0)) {
      /*
       * Delay the initialization of callFileChooser in order to delay the
       * creation of the recorder.
       */
      if (callFileChooser == null) {
        callFileChooser =
            GenericFileDialog.create(
                null,
                resources.getI18NString("plugin.callrecordingconfig.SAVE_CALL"),
                SipCommFileChooser.SAVE_FILE_OPERATION);
        callFileChooser.addFilter(
            new SipCommFileFilter() {
              @Override
              public boolean accept(File f) {
                return f.isDirectory() || isSupportedFormat(f);
              }

              @Override
              public String getDescription() {
                StringBuilder description = new StringBuilder();

                description.append("Recorded call");

                Recorder recorder;

                try {
                  recorder = getRecorder();
                } catch (OperationFailedException ofex) {
                  logger.error("Failed to get Recorder", ofex);
                  recorder = null;
                }
                if (recorder != null) {
                  List<String> supportedFormats = recorder.getSupportedFormats();

                  if (supportedFormats != null) {
                    description.append(" (");

                    boolean firstSupportedFormat = true;

                    for (String supportedFormat : supportedFormats) {
                      if (firstSupportedFormat) firstSupportedFormat = false;
                      else description.append(", ");
                      description.append("*.");
                      description.append(supportedFormat);
                    }

                    description.append(')');
                  }
                }
                return description.toString();
              }
            });
      }
      // Offer a default name for the file to record into.
      callFileChooser.setStartPath(createDefaultFilename(null));

      File selectedFile = callFileChooser.getFileFromDialog();

      if (selectedFile != null) {
        callFilename = selectedFile.getAbsolutePath();

        /*
         * If the user specified no extension (which seems common on Mac
         * OS X at least) i.e. no format, then it is not obvious that we
         * have to override the set Recorder.CALL_FORMAT.
         */
        callFormat = SoundFileUtils.getExtension(selectedFile);

        if ((callFormat != null) && (callFormat.length() != 0)) {
          /*
           * If the use has specified an extension and thus a format
           * which is not supported, use a default format instead.
           */
          if (!isSupportedFormat(selectedFile)) {
            /*
             * If what appears to be an extension seems a lot like
             * an extension, then it should be somewhat safer to
             * replace it.
             */
            if (SoundFileUtils.isSoundFile(selectedFile)) {
              callFilename = callFilename.substring(0, callFilename.lastIndexOf('.'));
            }
            String configuredFormat = configuration.getString(Recorder.FORMAT);
            callFormat =
                (configuredFormat != null && configuredFormat.length() != 0)
                    ? configuredFormat
                    : SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;

            callFilename += '.' + callFormat;
          }
          configuration.setProperty(Recorder.FORMAT, callFormat);
        }
      } else {
        // user canceled the recording
        return false;
      }
    } else {
      callFilename = createDefaultFilename(savedCallsPath);
      callFormat = SoundFileUtils.getExtension(new File(callFilename));
    }

    Throwable exception = null;

    try {
      Recorder recorder = getRecorder();

      if (recorder != null) {
        if ((callFormat == null) || (callFormat.length() <= 0))
          callFormat = SoundFileUtils.DEFAULT_CALL_RECORDING_FORMAT;

        recorder.start(callFormat, callFilename);
      }

      this.recorder = recorder;
    } catch (IOException ioex) {
      exception = ioex;
    } catch (MediaException mex) {
      exception = mex;
    } catch (OperationFailedException ofex) {
      exception = ofex;
    }
    if ((recorder == null) || (exception != null)) {
      logger.error(
          "Failed to start recording call " + call + " into file " + callFilename, exception);
      return false;
    } else return true;
  }
}
コード例 #11
0
/**
 * A dialog dedicated to desktop streaming/sharing. Shows the possible screens to select from to use
 * for the streaming/sharing session.
 *
 * @author Yana Stamcheva
 */
public class SelectScreenDialog extends SIPCommDialog {
  /** Serial version UID. */
  private static final long serialVersionUID = 0L;

  /** The object used for logging. */
  private static final Logger logger = Logger.getLogger(SelectScreenDialog.class);

  /** The combo box containing screen choice. */
  private final JComboBox deviceComboBox;

  /** The cancel button of this dialog. */
  private final JButton cancelButton =
      new JButton(GuiActivator.getResources().getI18NString("service.gui.CANCEL"));

  /**
   * The video <code>CaptureDeviceInfo</code> this instance started to create the preview of.
   *
   * <p>Because the creation of the preview is asynchronous, it's possible to request the preview of
   * one and the same device multiple times. Which may lead to failures because of, for example,
   * busy devices and/or resources (as is the case with LTI-CIVIL and video4linux2).
   */
  private static MediaDevice videoDeviceInPreview;

  /** The selected media device. */
  private MediaDevice selectedDevice;

  /**
   * Creates an instance of <tt>SelectScreenDialog</tt> by specifying the list of possible desktop
   * devices to choose from.
   *
   * @param desktopDevices the list of possible desktop devices to choose from
   */
  public SelectScreenDialog(List<MediaDevice> desktopDevices) {
    setModal(true);

    setPreferredSize(new Dimension(400, 300));

    Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout());

    deviceComboBox = new JComboBox(desktopDevices.toArray());
    contentPane.add(deviceComboBox, BorderLayout.NORTH);

    deviceComboBox.setRenderer(new ComboRenderer());

    contentPane.add(createPreview(deviceComboBox));

    contentPane.add(createButtonsPanel(), BorderLayout.SOUTH);
  }

  /**
   * Returns the selected device.
   *
   * @return the selected device
   */
  public MediaDevice getSelectedDevice() {
    return selectedDevice;
  }

  /**
   * Creates the buttons panel.
   *
   * @return the buttons panel
   */
  private Component createButtonsPanel() {
    JPanel buttonsPanel = new TransparentPanel(new FlowLayout(FlowLayout.RIGHT));

    JButton okButton = new JButton(GuiActivator.getResources().getI18NString("service.gui.OK"));

    okButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = (MediaDevice) deviceComboBox.getSelectedItem();

            dispose();
          }
        });

    buttonsPanel.add(okButton);

    cancelButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            selectedDevice = null;
            dispose();
          }
        });

    buttonsPanel.add(cancelButton);

    return buttonsPanel;
  }

  /**
   * Create preview component.
   *
   * @param comboBox the options.
   * @return the component.
   */
  private static Component createPreview(final JComboBox comboBox) {
    final JComponent preview;

    JLabel noPreview =
        new JLabel(GuiActivator.getResources().getI18NString("impl.media.configform.NO_PREVIEW"));
    noPreview.setHorizontalAlignment(SwingConstants.CENTER);
    noPreview.setVerticalAlignment(SwingConstants.CENTER);

    preview = createVideoContainer(noPreview);

    preview.setPreferredSize(new Dimension(WIDTH, 280));
    preview.setMaximumSize(new Dimension(WIDTH, 280));

    final ActionListener comboBoxListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            MediaDevice device = (MediaDevice) comboBox.getSelectedItem();

            if ((device != null) && device.equals(videoDeviceInPreview)) return;

            Exception exception;
            try {
              createPreview(device, preview);
              exception = null;
            } catch (IOException ex) {
              exception = ex;
            } catch (MediaException ex) {
              exception = ex;
            }
            if (exception != null) {
              logger.error("Failed to create preview for device " + device, exception);

              device = null;
            }

            videoDeviceInPreview = device;
          }
        };
    comboBox.addActionListener(comboBoxListener);

    /*
     * We have to initialize the controls to reflect the configuration
     * at the time of creating this instance. Additionally, because the
     * video preview will stop when it and its associated controls
     * become unnecessary, we have to restart it when the mentioned
     * controls become necessary again. We'll address the two goals
     * described by pretending there's a selection in the video combo
     * box when the combo box in question becomes displayable.
     */
    comboBox.addHierarchyListener(
        new HierarchyListener() {
          public void hierarchyChanged(HierarchyEvent event) {
            if (((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
                && comboBox.isDisplayable()) {
              // let current changes end their execution
              // and after that trigger action on combobox
              SwingUtilities.invokeLater(
                  new Runnable() {
                    public void run() {
                      comboBoxListener.actionPerformed(null);
                    }
                  });
            } else {
              if (!comboBox.isDisplayable()) videoDeviceInPreview = null;
            }
          }
        });

    return preview;
  }

  /**
   * Creates preview for the device(video) in the video container.
   *
   * @param device the device
   * @param videoContainer the container
   * @throws IOException a problem accessing the device.
   * @throws MediaException a problem getting preview.
   */
  private static void createPreview(MediaDevice device, final JComponent videoContainer)
      throws IOException, MediaException {
    videoContainer.removeAll();

    videoContainer.revalidate();
    videoContainer.repaint();

    if (device == null) return;

    Component c =
        (Component)
            GuiActivator.getMediaService()
                .getVideoPreviewComponent(
                    device, videoContainer.getSize().width, videoContainer.getSize().height);

    videoContainer.add(c);
  }

  /**
   * Creates the video container.
   *
   * @param noVideoComponent the container component.
   * @return the video container.
   */
  private static JComponent createVideoContainer(Component noVideoComponent) {
    return new VideoContainer(noVideoComponent, false);
  }

  /** Custom combo box renderer. */
  private static class ComboRenderer extends DefaultListCellRenderer {
    @Override
    public Component getListCellRendererComponent(
        JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
      super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

      MediaDevice mediaDevice = (MediaDevice) value;

      Dimension screenSize = null;
      if (mediaDevice != null) screenSize = ((VideoMediaFormat) mediaDevice.getFormat()).getSize();

      this.setText(screenSize.width + "x" + screenSize.height);

      return this;
    }
  }

  /**
   * Automatically press the cancel button when this dialog has been escaped.
   *
   * @param escaped indicates if this dialog has been closed by pressing the ESC key
   */
  @Override
  protected void close(boolean escaped) {
    if (escaped) cancelButton.doClick();
  }
}
コード例 #12
0
  /**
   * Create preview component.
   *
   * @param comboBox the options.
   * @return the component.
   */
  private static Component createPreview(final JComboBox comboBox) {
    final JComponent preview;

    JLabel noPreview =
        new JLabel(GuiActivator.getResources().getI18NString("impl.media.configform.NO_PREVIEW"));
    noPreview.setHorizontalAlignment(SwingConstants.CENTER);
    noPreview.setVerticalAlignment(SwingConstants.CENTER);

    preview = createVideoContainer(noPreview);

    preview.setPreferredSize(new Dimension(WIDTH, 280));
    preview.setMaximumSize(new Dimension(WIDTH, 280));

    final ActionListener comboBoxListener =
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            MediaDevice device = (MediaDevice) comboBox.getSelectedItem();

            if ((device != null) && device.equals(videoDeviceInPreview)) return;

            Exception exception;
            try {
              createPreview(device, preview);
              exception = null;
            } catch (IOException ex) {
              exception = ex;
            } catch (MediaException ex) {
              exception = ex;
            }
            if (exception != null) {
              logger.error("Failed to create preview for device " + device, exception);

              device = null;
            }

            videoDeviceInPreview = device;
          }
        };
    comboBox.addActionListener(comboBoxListener);

    /*
     * We have to initialize the controls to reflect the configuration
     * at the time of creating this instance. Additionally, because the
     * video preview will stop when it and its associated controls
     * become unnecessary, we have to restart it when the mentioned
     * controls become necessary again. We'll address the two goals
     * described by pretending there's a selection in the video combo
     * box when the combo box in question becomes displayable.
     */
    comboBox.addHierarchyListener(
        new HierarchyListener() {
          public void hierarchyChanged(HierarchyEvent event) {
            if (((event.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0)
                && comboBox.isDisplayable()) {
              // let current changes end their execution
              // and after that trigger action on combobox
              SwingUtilities.invokeLater(
                  new Runnable() {
                    public void run() {
                      comboBoxListener.actionPerformed(null);
                    }
                  });
            } else {
              if (!comboBox.isDisplayable()) videoDeviceInPreview = null;
            }
          }
        });

    return preview;
  }