⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outgoingcall.java.svn-base

📁 开源项目openfire的完整源程序
💻 SVN-BASE
字号:
/**
 * $Revision: $
 * $Date: $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.sparkplugin;

import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.jingle.JingleNegotiator;
import org.jivesoftware.smackx.jingle.JingleSession;
import org.jivesoftware.smackx.jingle.OutgoingJingleSession;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionListener;
import org.jivesoftware.smackx.jingle.listeners.JingleSessionStateListener;
import org.jivesoftware.smackx.jingle.media.PayloadType;
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.phone.PhoneManager;
import org.jivesoftware.spark.component.FileDragLabel;
import org.jivesoftware.spark.ui.ChatRoom;
import org.jivesoftware.spark.ui.ChatRoomClosingListener;
import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactList;
import org.jivesoftware.spark.util.SwingTimerTask;
import org.jivesoftware.spark.util.TaskEngine;
import org.jivesoftware.spark.util.log.Log;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;

/**
 * Handles UI controls for outgoing jingle calls.
 */
public class OutgoingCall extends JPanel implements JingleSessionStateListener, JingleSessionListener, ChatRoomClosingListener {

    private FileDragLabel imageLabel = new FileDragLabel();
    private JLabel titleLabel = new JLabel();
    private JLabel fileLabel = new JLabel();

    private CallButton cancelButton = new CallButton();

    private OutgoingJingleSession session;
    private JingleRoom jingleRoom;

    private AudioClip ringing;

    private ChatRoom chatRoom;

    private boolean established = false;

    private boolean mediaReceived = false;

    private TimerTask mediaReceivedTask;

    private static final long WAIT_FOR_MEDIA_DELAY = 20000;

    /**
     * Creates a new instance of OutgoingCall.
     */
    public OutgoingCall() {
        try {
            ringing = Applet.newAudioClip(JinglePhoneRes.getURL("RINGING"));
        }
        catch (Exception e) {
            Log.error(e);
        }

        setLayout(new GridBagLayout());

        setBackground(new Color(250, 249, 242));
        add(imageLabel, new GridBagConstraints(0, 0, 1, 3, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));

        add(titleLabel, new GridBagConstraints(1, 0, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
        titleLabel.setFont(new Font("Dialog", Font.BOLD, 11));
        titleLabel.setForeground(new Color(211, 174, 102));

        cancelButton.setText("Cancel");
        add(cancelButton, new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));

        cancelButton.setForeground(new Color(73, 113, 196));
        cancelButton.setFont(new Font("Dialog", Font.BOLD, 11));
        cancelButton.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(73, 113, 196)));

        setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.white));
    }

    /**
     * Handles a new outgoing call.
     *
     * @param session  the JingleSession for the outgoing call.
     * @param chatRoom the room the session is associated with.
     * @param jid      the users jid.
     */
    public void handleOutgoingCall(final OutgoingJingleSession session, ChatRoom chatRoom, final String jid) {
        this.chatRoom = chatRoom;

        JingleStateManager.getInstance().addJingleSession(chatRoom, JingleStateManager.JingleRoomState.ringing);

        chatRoom.addClosingListener(this);
        session.addListener(this);
        session.addStateListener(this);
        cancelButton.setVisible(true);

        this.session = session;

        this.session.addStateListener(this);

        // Start the call
        if (this.session != null) {
            this.session.start();
        }

        fileLabel.setText(jid);

        ContactList contactList = SparkManager.getWorkspace().getContactList();
        ContactItem contactItem = contactList.getContactItemByJID(jid);


        titleLabel.setText("Outgoing Voice Chat To " + contactItem.getNickname());


        cancelButton.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                cancel();
            }

            public void mouseEntered(MouseEvent e) {
                cancelButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            }

            public void mouseExited(MouseEvent e) {
                cancelButton.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        });

        makeClickable(imageLabel);
        makeClickable(titleLabel);

        // Notify state change
        SparkManager.getChatManager().notifySparkTabHandlers(chatRoom);

        updateOutgoingCallPanel();
    }

    /**
     * Updates the UI to reflect the current state.
     */
    private void updateOutgoingCallPanel() {
        if (session == null || session.isClosed()) {
            return;
        }
        else if (session instanceof OutgoingJingleSession) {
            showAlert(false);
            if (session.getState() instanceof OutgoingJingleSession.Inviting) {
                titleLabel.setText("Calling user. Please wait...");
                cancelButton.setVisible(true);
            }
        }
    }


    /**
     * Called when the call has been answered. Will append the JingleRoom to the
     * associated ChatRoom.
     */
    private void showCallAnsweredState() {
        final SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy h:mm a");
        titleLabel.setText("Voice chat started on " + formatter.format(new Date()));
        cancelButton.setVisible(false);
        if (ringing != null) {
            ringing.stop();
        }

        jingleRoom = new JingleRoom(session, chatRoom);
        chatRoom.getChatPanel().add(jingleRoom, new GridBagConstraints(1, 1, 1, 1, 0.05, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
        chatRoom.getChatPanel().invalidate();
        chatRoom.getChatPanel().validate();
        chatRoom.getChatPanel().repaint();

        // Add state
        JingleStateManager.getInstance().addJingleSession(chatRoom, JingleStateManager.JingleRoomState.inJingleCall);

        // Notify state change
        SparkManager.getChatManager().notifySparkTabHandlers(chatRoom);
    }

    /**
     * Called when the call has ended.
     */
    private void showCallEndedState(String reason) {
        titleLabel.setText(reason);

        showAlert(true);
        cancelButton.setVisible(false);
        if (ringing != null) {
            ringing.stop();
        }

        if (chatRoom != null && jingleRoom != null) {
            chatRoom.getChatPanel().remove(jingleRoom);
            chatRoom.getChatPanel().invalidate();
            chatRoom.getChatPanel().validate();
            chatRoom.getChatPanel().repaint();
        }

        // Add state
        JingleStateManager.getInstance().removeJingleSession(chatRoom);

        // Notify state change
        SparkManager.getChatManager().notifySparkTabHandlers(chatRoom);
    }

    private void makeClickable(final JComponent component) {
        component.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
            }

            public void mouseEntered(MouseEvent e) {
                component.setCursor(new Cursor(Cursor.HAND_CURSOR));
            }

            public void mouseExited(MouseEvent e) {
                component.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        });
    }

    private class CallButton extends JButton {

        public CallButton() {
            decorate();
        }

        /**
         * Create a new RolloverButton.
         *
         * @param text the button text.
         * @param icon the button icon.
         */
        public CallButton(String text, Icon icon) {
            super(text, icon);
            decorate();
        }

        /**
         * Decorates the button with the approriate UI configurations.
         */
        private void decorate() {
            setBorderPainted(false);
            setOpaque(true);

            setContentAreaFilled(false);
            setMargin(new Insets(1, 1, 1, 1));
        }

    }

    /**
     * Changes the background color. If alert is true, the background will reflect that the ui
     * needs attention.
     *
     * @param alert true to notify users that their attention is needed.
     */
    private void showAlert(boolean alert) {
        if (alert) {
            titleLabel.setForeground(new Color(211, 174, 102));
            setBackground(new Color(250, 249, 242));
        }
        else {
            setBackground(new Color(239, 245, 250));
            titleLabel.setForeground(new Color(65, 139, 179));
        }
    }

    /**
     * Call to cancel phone conversation.
     */
    public void cancel() {
        if (session != null) {
            try {
                session.terminate();
                session = null;
            }
            catch (XMPPException e) {
                Log.error(e);
            }
        }
        final SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy h:mm a");
        showCallEndedState("Voice chat ended on " + formatter.format(new Date()));
    }

    public void beforeChange(JingleNegotiator.State old, JingleNegotiator.State newOne) throws JingleNegotiator.JingleException {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                updateOutgoingCallPanel();
            }
        });
    }

    public void afterChanged(JingleNegotiator.State old, JingleNegotiator.State newOne) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                updateOutgoingCallPanel();
            }
        });
    }


    public void closing() {
        if (session != null) {
            try {
                session.terminate();
            }
            catch (XMPPException e) {
                Log.error(e);
            }
        }

        JingleStateManager.getInstance().removeJingleSession(chatRoom);
    }

    public void sessionMediaReceived(JingleSession jingleSession, String participant) {
        mediaReceived = true;
        TaskEngine.getInstance().cancelScheduledTask(mediaReceivedTask);
        showCallAnsweredState();
    }

    public void sessionEstablished(PayloadType payloadType, TransportCandidate transportCandidate, TransportCandidate transportCandidate1, JingleSession jingleSession) {
        established = true;
        mediaReceivedTask = new SwingTimerTask() {
            public void doRun() {
                if (!mediaReceived) {
                    if (session != null) {
                        try {
                            session.terminate("No Media Received. This may be caused by firewall configuration problems.");
                        }
                        catch (XMPPException e) {
                            Log.error(e);
                        }
                    }
                }
            }
        };
        TaskEngine.getInstance().schedule(mediaReceivedTask, WAIT_FOR_MEDIA_DELAY, WAIT_FOR_MEDIA_DELAY);
    }

    public void sessionDeclined(String string, JingleSession jingleSession) {
        showCallEndedState("The Session was rejected.");
    }

    public void sessionRedirected(String string, JingleSession jingleSession) {
    }

    public void sessionClosed(String string, JingleSession jingleSession) {
        
        if (jingleSession instanceof OutgoingJingleSession) {
            if (established && mediaReceived) {
                final SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy h:mm a");
                showCallEndedState("Voice chat ended on " + formatter.format(new Date()));
            }
            else {
                showCallEndedState("Session closed due to " + string);
            }
        }
        if(PhoneManager.isUseStaticLocator()&&PhoneManager.isUsingMediaLocator()){
            PhoneManager.setUsingMediaLocator(false);
        }
    }

    public void sessionClosedOnError(XMPPException xmppException, JingleSession jingleSession) {
        showCallEndedState("Voice chat ended due: " + xmppException.getMessage());
        if(PhoneManager.isUseStaticLocator()&&PhoneManager.isUsingMediaLocator()){
            PhoneManager.setUsingMediaLocator(false);
        }                
    }


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -