/** * Creates a new AWT <tt>Container</tt> which can display a single <tt>Component</tt> at a time * (supposedly, one which represents video) and, in the absence of such a <tt>Component</tt>, * displays a predefined default <tt>Component</tt> (in accord with the previous supposition, one * which is the default when there is no video). The returned <tt>Container</tt> will track the * <tt>Components</tt>s added to and removed from it in order to make sure that * <tt>noVideoContainer</tt> is displayed as described. * * @param noVideoComponent the predefined default <tt>Component</tt> to be displayed in the * returned <tt>Container</tt> when there is no other <tt>Component</tt> in it * @return a new <tt>Container</tt> which can display a single <tt>Component</tt> at a time and, * in the absence of such a <tt>Component</tt>, displays <tt>noVideoComponent</tt> */ private VideoContainer createVideoContainer(Component noVideoComponent) { Container oldParent = noVideoComponent.getParent(); if (oldParent != null) oldParent.remove(noVideoComponent); return new VideoContainer(noVideoComponent, false); }
/** * Releases the resources acquired by this instance which require explicit disposal (e.g. any * listeners added to the depicted <tt>CallPeer</tt>. Invoked by <tt>OneToOneCallPanel</tt> when * it determines that this <tt>OneToOneCallPeerPanel</tt> is no longer necessary. */ public void dispose() { disposed = true; callPeerAdapter.dispose(); uiVideoHandler.deleteObserver(uiVideoHandlerObserver); if (callRenderer instanceof Component) { ((Component) callRenderer).removePropertyChangeListener(CallContainer.PROP_FULL_SCREEN, this); } }
/** * Re-dispatches glass pane mouse events only in case they occur on the security panel. * * @param glassPane the glass pane * @param e the mouse event in question */ private void redispatchMouseEvent(Component glassPane, MouseEvent e) { Point glassPanePoint = e.getPoint(); Point securityPanelPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, securityPanel); Component component; Point componentPoint; if (securityPanelPoint.y > 0) { component = securityPanel; componentPoint = securityPanelPoint; } else { Container contentPane = callRenderer.getCallContainer().getCallWindow().getFrame().getContentPane(); Point containerPoint = SwingUtilities.convertPoint(glassPane, glassPanePoint, contentPane); component = SwingUtilities.getDeepestComponentAt(contentPane, containerPoint.x, containerPoint.y); componentPoint = SwingUtilities.convertPoint(contentPane, glassPanePoint, component); } if (component != null) component.dispatchEvent( new MouseEvent( component, e.getID(), e.getWhen(), e.getModifiers(), componentPoint.x, componentPoint.y, e.getClickCount(), e.isPopupTrigger())); e.consume(); }
/** * Gathers Jingle Nodes candidates for all host <tt>Candidate</tt>s that are already present in * the specified <tt>component</tt>. This method relies on the specified <tt>component</tt> to * already contain all its host candidates so that it would resolve them. * * @param component the {@link Component} that we'd like to gather candidate Jingle Nodes * <tt>Candidate</tt>s for * @return the <tt>LocalCandidate</tt>s gathered by this <tt>CandidateHarvester</tt> */ @Override public synchronized Collection<LocalCandidate> harvest(Component component) { logger.info("harvest Jingle Nodes"); Collection<LocalCandidate> candidates = new HashSet<LocalCandidate>(); String ip = null; int port = -1; /* if we have already a candidate (RTCP) allocated, get it */ if (localAddressSecond != null && relayedAddressSecond != null) { LocalCandidate candidate = createJingleNodesCandidate(relayedAddressSecond, component, localAddressSecond); // try to add the candidate to the component and then only add it to // the harvest not redundant (not sure how it could be red. but ...) if (component.addLocalCandidate(candidate)) { candidates.add(candidate); } localAddressSecond = null; relayedAddressSecond = null; return candidates; } XMPPConnection conn = serviceNode.getConnection(); JingleChannelIQ ciq = null; if (serviceNode != null) { final TrackerEntry preferred = serviceNode.getPreferedRelay(); if (preferred != null) { ciq = SmackServiceNode.getChannel(conn, preferred.getJid()); } } if (ciq != null) { ip = ciq.getHost(); port = ciq.getRemoteport(); if (logger.isInfoEnabled()) { logger.info( "JN relay: " + ip + " remote port:" + port + " local port: " + ciq.getLocalport()); } if (ip == null || ciq.getRemoteport() == 0) { logger.warn("JN relay ignored because ip was null or port 0"); return candidates; } // Drop the scope or interface name if the relay sends it // along in its IPv6 address. The scope/ifname is only valid on the // host that owns the IP and we don't need it here. int scopeIndex = ip.indexOf('%'); if (scopeIndex > 0) { logger.warn("Dropping scope from assumed IPv6 address " + ip); ip = ip.substring(0, scopeIndex); } /* RTP */ TransportAddress relayedAddress = new TransportAddress(ip, port, Transport.UDP); TransportAddress localAddress = new TransportAddress(ip, ciq.getLocalport(), Transport.UDP); LocalCandidate local = createJingleNodesCandidate(relayedAddress, component, localAddress); /* RTCP */ relayedAddressSecond = new TransportAddress(ip, port + 1, Transport.UDP); localAddressSecond = new TransportAddress(ip, ciq.getLocalport() + 1, Transport.UDP); // try to add the candidate to the component and then only add it to // the harvest not redundant (not sure how it could be red. but ...) if (component.addLocalCandidate(local)) { candidates.add(local); } } return candidates; }
/** * Creates a <tt>CallPeerPanel</tt> for the given call peer. * * @param callRenderer the renderer of the call * @param callPeer the <tt>CallPeer</tt> represented in this panel * @param uiVideoHandler the facility which is to aid the new instance in the dealing with the * video-related information */ public OneToOneCallPeerPanel( SwingCallRenderer callRenderer, CallPeer callPeer, UIVideoHandler2 uiVideoHandler) { this.callRenderer = callRenderer; this.callPeer = callPeer; // we need to obtain call as soon as possible // cause if it fails too quickly we may fail to show it this.call = callPeer.getCall(); this.uiVideoHandler = uiVideoHandler; peerName = CallManager.getPeerDisplayName(callPeer); securityPanel = SecurityPanel.create(this, callPeer, null); photoLabel = new JLabel(getPhotoLabelIcon()); center = createCenter(); statusBar = createStatusBar(); setPeerImage(CallManager.getPeerImage(callPeer)); /* Lay out the main Components of the UI. */ setLayout(new GridBagLayout()); GridBagConstraints cnstrnts = new GridBagConstraints(); if (center != null) { cnstrnts.fill = GridBagConstraints.BOTH; cnstrnts.gridx = 0; cnstrnts.gridy = 1; cnstrnts.weightx = 1; cnstrnts.weighty = 1; add(center, cnstrnts); } if (statusBar != null) { cnstrnts.fill = GridBagConstraints.NONE; cnstrnts.gridx = 0; cnstrnts.gridy = 3; cnstrnts.weightx = 0; cnstrnts.weighty = 0; cnstrnts.insets = new Insets(5, 0, 0, 0); add(statusBar, cnstrnts); } createSoundLevelIndicators(); initSecuritySettings(); /* * Add the listeners which will be notified about changes in the model * and which will update this view. */ callPeerAdapter = new CallPeerAdapter(callPeer, this); uiVideoHandler.addObserver(uiVideoHandlerObserver); /* * This view adapts to whether it is displayed in full-screen or * windowed mode. */ if (callRenderer instanceof Component) { ((Component) callRenderer).addPropertyChangeListener(CallContainer.PROP_FULL_SCREEN, this); } OperationSetDesktopSharingClient desktopSharingClient = callPeer.getProtocolProvider().getOperationSet(OperationSetDesktopSharingClient.class); if (desktopSharingClient != null) { desktopSharingMouseAndKeyboardListener = new DesktopSharingMouseAndKeyboardListener(callPeer, desktopSharingClient); } else desktopSharingMouseAndKeyboardListener = null; updateViewFromModel(); }