Package org.jdesktop.wonderland.modules.assetmeter.client

Source Code of org.jdesktop.wonderland.modules.assetmeter.client.AssetMeterJPanel

/**
* Open Wonderland
*
* Copyright (c) 2011 - 2012, Open Wonderland Foundation, All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* The Open Wonderland Foundation designates this particular file as
* subject to the "Classpath" exception as provided by the Open Wonderland
* Foundation in the License file that accompanied this code.
*/

/*
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.assetmeter.client;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import org.jdesktop.wonderland.client.assetmgr.Asset;
import org.jdesktop.wonderland.client.assetmgr.AssetManager;
import org.jdesktop.wonderland.client.assetmgr.AssetManager.AssetProgressListener;

/**
*
* @author jkaplan
* @author Ronny Standtke <ronny.standtke@fhnw.ch>
*/
public class AssetMeterJPanel extends javax.swing.JPanel {

    private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(
            "org/jdesktop/wonderland/modules/assetmeter/client/resources/Bundle");
    /**
     * A synchronized ordered map of Assets to their downloading status objects
     */
    private final Map<String, DownloadingAsset> downloadingAssetMap;

    /* The default list model */
    private final AssetIndicatorListModel listModel = new AssetIndicatorListModel();

    /* The progress listener */
    private final MeterProgressListener progressListener;

    /* The ClientPlugin */
    private final AssetMeterClientPlugin plugin;

    /* The fade timer in progress */
    private Timer dismissTimer;

    /* Whether this component is enabled */
    private boolean enabled = true;

    /** Creates new form AssetMeterJFrame */
    public AssetMeterJPanel(AssetMeterClientPlugin plugin) {
        this.plugin = plugin;

        initComponents();
        downloadingAssetMap = Collections.synchronizedMap(new LinkedHashMap());

        // Have the JList renderer the asset indicators
        loadingAssetList.setModel(listModel);
        loadingAssetList.setCellRenderer(new AssetIndicatorCellRenderer());

        // Add a listener to the asset manager
        progressListener = new MeterProgressListener();
       
        // Select the right card
        ((CardLayout) getLayout()).show(this, "combined");
    }

    /**
     * Register the progress listener with the asset manager
     */
    public void register() {
        AssetManager manager = AssetManager.getAssetManager();
        manager.addProgressListener(progressListener);
    }
   
    /**
     * Stop listener for events
     */
    public void deactivate() {
        AssetManager manager = AssetManager.getAssetManager();
        manager.removeProgressListener(progressListener);
    }
   
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        individualPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        loadingAssetList = new javax.swing.JList();
        jPanel1 = new javax.swing.JPanel();
        downButton = new javax.swing.JButton();
        combinedPanel = new javax.swing.JPanel();
        combinedProgressBar = new javax.swing.JProgressBar();
        combinedLabel = new javax.swing.JLabel();
        upButton = new javax.swing.JButton();

        setMaximumSize(new java.awt.Dimension(300, 300));
        setPreferredSize(new java.awt.Dimension(300, 40));
        setLayout(new java.awt.CardLayout());

        individualPanel.setLayout(new java.awt.BorderLayout());

        jScrollPane1.setViewportView(loadingAssetList);

        individualPanel.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel1.setPreferredSize(new java.awt.Dimension(300, 10));

        downButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/jdesktop/wonderland/modules/assetmeter/client/resources/downArrow23x10.png"))); // NOI18N
        downButton.setBorder(null);
        downButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap(320, Short.MAX_VALUE)
                .add(downButton))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jPanel1Layout.createSequentialGroup()
                .add(downButton)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        individualPanel.add(jPanel1, java.awt.BorderLayout.NORTH);

        add(individualPanel, "individual");

        combinedPanel.setMaximumSize(new java.awt.Dimension(300, 400));
        combinedPanel.setMinimumSize(new java.awt.Dimension(300, 25));
        combinedPanel.setPreferredSize(new java.awt.Dimension(300, 40));

        combinedLabel.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        combinedLabel.setText("100 files");

        upButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/jdesktop/wonderland/modules/assetmeter/client/resources/upArrow23x10.png"))); // NOI18N
        upButton.setBorder(null);
        upButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                upButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout combinedPanelLayout = new org.jdesktop.layout.GroupLayout(combinedPanel);
        combinedPanel.setLayout(combinedPanelLayout);
        combinedPanelLayout.setHorizontalGroup(
            combinedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(org.jdesktop.layout.GroupLayout.TRAILING, combinedPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(combinedProgressBar, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 241, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(combinedLabel)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(upButton)
                .addContainerGap())
        );
        combinedPanelLayout.setVerticalGroup(
            combinedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(combinedPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(combinedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
                    .add(combinedProgressBar, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(combinedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(upButton)
                        .add(combinedLabel)))
                .addContainerGap(13, Short.MAX_VALUE))
        );

        add(combinedPanel, "combined");
    }// </editor-fold>//GEN-END:initComponents

    private void upButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_upButtonActionPerformed
        ((CardLayout) getLayout()).show(this, "individual");
        setSize(getMaximumSize());
        invalidate();
        individualPanel.invalidate();
        plugin.resize();
    }//GEN-LAST:event_upButtonActionPerformed

    private void downButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downButtonActionPerformed
        ((CardLayout) getLayout()).show(this, "combined");
        setSize(getPreferredSize());
        invalidate();
        plugin.resize();
    }//GEN-LAST:event_downButtonActionPerformed

    private void fadeIn() {
        // OWL issue #241 - fade in on AWT event thread
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                plugin.getHUDComponent().setVisible(true);
            }
        });
       
       
//        if (fadeTimer != null) {
//            fadeTimer.stop();
//        }
//
//        if (!plugin.getHUDComponent().isVisible()) {
//           plugin.getHUDComponent().setVisible(true);
//        }
//
//        transparency = 0;
//        if (plugin.getHUDComponent().getTransparency() != 0) {
//            plugin.getHUDComponent().setTransparency(0f);
//        }
    }

    private void fadeOut() {
        // OWL issue #241 - fade out on AWT event thread
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // wait 10 seconds before dismissing meter to prevent meter from
                // popping in and out of view
                if (dismissTimer == null) {
                    dismissTimer = new Timer(10000, new ActionListener() {
                       
                        public void actionPerformed(ActionEvent e) {
                            if (downloadingAssetMap.size() == 0) {
                                plugin.getHUDComponent().setVisible(false);
                                dismissTimer = null;
                            } else {
                                dismissTimer.restart();
                            }
                        }
                    });
                    dismissTimer.setRepeats(false);
                    dismissTimer.start();
                }
            }
        });
       
//        if (fadeTimer != null && fadeTimer.isRunning()) {
//            fadeTimer.stop();
//        }
//
//        // see if we are already faded out
//        if (transparency == 100) {
//            return;
//        }
//
//        fadeTimer = new Timer(100, new ActionListener() {
//            public void actionPerformed(ActionEvent e) {
//                if (transparency < 100) {
//                    transparency += 2;
//                    plugin.getHUDComponent().setTransparency(transparency / 100f);
//                } else {
//                    transparency = 100;
//                    ((Timer) e.getSource()).stop();
//
//                    if (plugin.getHUDComponent().isVisible()) {
//                        plugin.getHUDComponent().setVisible(false);
//                    }
//                }
//            }
//        });
//        fadeTimer.start();
    }

    void setUpdateEnabled(boolean enabled) {
        this.enabled = enabled;

        if (enabled && downloadingAssetMap.size() > 0) {
            fadeIn();
        } else if (!enabled) {
            fadeOut();
        }
    }

    /**
     * Updates the given downloading asset
     */
    private void updateDownloadingAsset(
            Asset asset, final int readBytes, final int percent) {
        // Update the values in the downloading asset indicator using a swing
        // worker for thread safeness.
        final Asset[] assetArray = new Asset[]{asset};
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                DownloadingAsset da = downloadingAssetMap.get(
                        assetArray[0].getAssetURI().toExternalForm());
                if (da != null) {
                    da.readBytes = readBytes;
                    da.percentage = percent;
                    da.indicator.setAssetProgressValue(da.percentage);
                    listModel.updateElement(da.indicator);
                }
            }
        });

        updateCombined();
    }

    /**
     * Adds a new asset to the list. This updates the UI as necessary
     */
    private void addDownloadingAsset(final Asset asset) {
        // Adds a downloading asset to the list using a swing worker for thread
        // safeness
        final DownloadingAsset da = new DownloadingAsset();
        da.asset = asset;
        da.readBytes = 0;
        da.percentage = 0;
        final String assetURIString = asset.getAssetURI().toExternalForm();
        downloadingAssetMap.put(assetURIString, da);

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                // set up the indicator in the AWT event thread
                da.indicator = new AssetIndicator();
                da.indicator.setAssetProgressValue(0);
                da.indicator.setAssetLabel(assetURIString);

                listModel.addElementToTail(da.indicator);
            }
        });

        updateCombined();
    }

    /**
     * Removes a downloading asset from the list and updates the UI as
     * necessary.
     */
    private void removeDownloadingAsset(Asset asset) {
        // Removes a downloading asset from the list using a swing worker for
        // thread safeness
        final DownloadingAsset da = downloadingAssetMap.remove(
                asset.getAssetURI().toExternalForm());

        new Timer(750, new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                listModel.removeElement(da.indicator);
                ((Timer) e.getSource()).stop();
            }
        }).start();

        updateCombined();
    }

    /**
     * Update the global statistics
     */
    private void updateCombined() {
        int count = 0;
        int totalPercent = 0;

        synchronized (downloadingAssetMap) {
            for (DownloadingAsset da : downloadingAssetMap.values()) {
                count++;
                totalPercent += da.percentage;
            }
        }

        if (count == 0) {
            fadeOut();
        } else if (enabled) {
            fadeIn();
        }

        final int fCount = count;
        final int fPercent;
        if (fCount == 0) {
            fPercent = 0;
        } else {
            fPercent = (int) ((double) totalPercent / (double) count);
        }

        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                String text = BUNDLE.getString("Files");
                text = MessageFormat.format(text, fCount);
                combinedLabel.setText(text);
                combinedProgressBar.setValue(fPercent);
            }
        });
    }

    /**
     * A class that represents an asset currently being downloaded and its
     * status
     */
    class DownloadingAsset {

        public Asset asset = null;
        public int readBytes = 0;
        public int percentage = -1;
        private AssetIndicator indicator = null; // initialize later in AWT
        // event thread
    }

    /**
     * A progress listener for assets being downloaded by the Asset Manager
     */
    class MeterProgressListener implements AssetProgressListener {

        public void downloadProgress(
                Asset asset, int readBytes, int percentage) {
            // Check to see if the asset is already in the list, otherwise
            // add it. We need to synchronized according to the asset to make
            // sure we do not add it twice
            synchronized (this) {
                if (downloadingAssetMap.containsKey(
                        asset.getAssetURI().toExternalForm()) == false) {
                    addDownloadingAsset(asset);
                } else {
                    updateDownloadingAsset(asset, readBytes, percentage);
                }
            }
        }

        public void downloadFailed(Asset asset) {
            // Simply try to remove the asset from the list, synchronized
            // on the asset
            synchronized (this) {
                removeDownloadingAsset(asset);
            }
        }

        public void downloadCompleted(Asset asset) {
            // Simply try to remove the asset from the list, synchrnoized
            // on the asset
            synchronized (this) {
                removeDownloadingAsset(asset);
            }
        }
    }

    /**
     * The list model to hold all of the asset indicators
     */
    class AssetIndicatorListModel extends AbstractListModel {

        /* An ordered list of downloading indicators */
        private List<AssetIndicator> indicatorList = new LinkedList();

        public int getSize() {
            return indicatorList.size();
        }

        public Object getElementAt(int index) {
            return indicatorList.get(index);
        }

        public synchronized void addElementToTail(AssetIndicator ai) {
            indicatorList.add(ai);
            int index = indicatorList.size() - 1;
            fireIntervalAdded(ai, index, index);
        }

        public synchronized void removeElement(AssetIndicator ai) {
            int index = indicatorList.indexOf(ai);
            if (index != -1) {
                indicatorList.remove(index);
                fireIntervalRemoved(this, index, index);
            }
        }

        public synchronized void updateElement(AssetIndicator ai) {
            int index = indicatorList.indexOf(ai);
            if (index != -1) {
                fireContentsChanged(this, index, index);
            }
        }
    }

    /**
     * A list cell rendered for the Asset Indicator
     */
    class AssetIndicatorCellRenderer implements ListCellRenderer {

        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean cellHasFocus) {
            return ((AssetIndicator) value);
        }
    }

    /**
     * A JPanel that holds a label and a progress bar.
     */
    class AssetIndicator extends JPanel {

        private JProgressBar progressBar;
        private JLabel assetLabel;

        /**
         * Constructor, assembles the components of the panel
         */
        public AssetIndicator() {
            super();

            // Make the layout a vertical box layout
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
            setBorder(BorderFactory.createEmptyBorder(4, 10, 2, 10));
            setAlignmentX(0.0f);
            setAlignmentY(0.0f);

            // Create the label, make the font a bit smaller and add it to
            // the panel
            assetLabel = new JLabel("");
            assetLabel.setAlignmentX(0.0f);
            assetLabel.setAlignmentY(0.0f);
            Font font = assetLabel.getFont();
            assetLabel.setFont(font.deriveFont(Font.PLAIN, 11));
//            assetLabel.setPreferredSize(getSize());
            add(assetLabel);

            // Create the progress bar and add it to the panel. Make sure it
            // is always of a maximum height
            progressBar = new JProgressBar();
//            progressBar.addComponentListener(new ComponentAdapter() {
//                @Override
//                public void componentResized(ComponentEvent e) {
//                    Dimension size = progressBar.getSize();
//                    size.setSize(size.getWidth(), 15);
//                    progressBar.setSize(size);
//                }
//
//            });
            progressBar.setAlignmentX(0.0f);
            progressBar.setAlignmentY(0.0f);
            progressBar.setValue(0);
//            progressBar.setPreferredSize(getSize());
            add(progressBar);
        }

        /**
         * Sets the value of the asset label.
         */
        public void setAssetLabel(String label) {
            assetLabel.setText(label);
        }

        /**
         * Sets the value of the progress bar.
         */
        public void setAssetProgressValue(int value) {
            progressBar.setValue(value);
        }

        /**
         * Increments the value of the progress bar by one
         */
        public void incrementAssetProgressValue() {
            progressBar.setValue(progressBar.getValue() + 1);
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel combinedLabel;
    private javax.swing.JPanel combinedPanel;
    private javax.swing.JProgressBar combinedProgressBar;
    private javax.swing.JButton downButton;
    private javax.swing.JPanel individualPanel;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JList loadingAssetList;
    private javax.swing.JButton upButton;
    // End of variables declaration//GEN-END:variables
}
TOP

Related Classes of org.jdesktop.wonderland.modules.assetmeter.client.AssetMeterJPanel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.