Package com.salas.bb.views

Source Code of com.salas.bb.views.ArticleListPanel$PagingPanel

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: ArticleListPanel.java,v 1.52 2008/04/02 14:31:28 spyromus Exp $
//

package com.salas.bb.views;

import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.value.ValueHolder;
import com.jgoodies.binding.value.ValueModel;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.uif.action.ActionManager;
import com.jgoodies.uif.action.ToggleAction;
import com.jgoodies.uif.builder.ToolBarBuilder;
import com.jgoodies.uif.util.SystemUtils;
import com.salas.bb.core.ControllerAdapter;
import com.salas.bb.core.GlobalController;
import com.salas.bb.core.GlobalModel;
import com.salas.bb.core.actions.ActionsTable;
import com.salas.bb.domain.IArticle;
import com.salas.bb.domain.IFeed;
import com.salas.bb.domain.IFeedListener;
import com.salas.bb.domain.prefs.UserPreferences;
import com.salas.bb.sentiments.SentimentsFeature;
import com.salas.bb.utils.i18n.Strings;
import com.salas.bb.utils.uif.CoolInternalFrame;
import com.salas.bb.utils.uif.JComboBoxActionItem;
import com.salas.bb.utils.uif.JumplessScrollPane;
import com.salas.bb.views.feeds.CompositeFeedDisplay;
import com.salas.bb.views.feeds.IFeedDisplay;
import com.salas.bb.views.settings.HTMLFeedDisplayConfig;
import com.salas.bb.views.settings.ImageFeedDisplayConfig;
import com.salas.bb.views.settings.RenderingManager;
import com.salas.bb.views.settings.RenderingSettingsNames;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseWheelEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.MessageFormat;

/**
* Display and work on the Articles of the selected Channel.
*/
public final class ArticleListPanel extends CoolInternalFrame implements PropertyChangeListener
{
    private final IFeedDisplay feedDisplay;
    private final JToolBar     subToolBar;

    /** Page number model. */
    private ValueModel pageModel;

    /**
     * Constructs panel with list of articles for selected channel.
     */
    public ArticleListPanel()
    {
        super(Strings.message("panel.articles"));

        setPreferredSize(new Dimension(300, 100));

        RenderingManager.addPropertyChangeListener(RenderingSettingsNames.THEME, this);

        // Register own controller listener
        GlobalController.SINGLETON.addControllerListener(new ControllerListener());
        PropertyChangeListener articleViewChangeHandler = new ArticleViewChangeHandler();
        GlobalModel.SINGLETON.getGlobalRenderingSettings().addPropertyChangeListener(
            "articleViewMode", articleViewChangeHandler);

        // Set the sub-toolbar (right justified in the CoolInternalFrame)
        pageModel = new ValueHolder(0);
        pageModel.addValueChangeListener(new PageModelListener());
        ValueModel pageCountModel = new ValueHolder(0);
        subToolBar = createSubtoolbar();
        setHeaderControl(subToolBar);

        // Create the list that will contain the channels. Uses a custom
        // renderer.
        HTMLFeedDisplayConfig htmlConfig = new HTMLFeedDisplayConfig();
        ImageFeedDisplayConfig imageConfig = new ImageFeedDisplayConfig();
        RenderingManager.addPropertyChangeListener(htmlConfig.getRenderingManagerListener());
        RenderingManager.addPropertyChangeListener(imageConfig.getRenderingManagerListener());

        // Get page size user preferences and subscribe to updates
        UserPreferences preferences = GlobalModel.SINGLETON.getUserPreferences();
        PropertyAdapter paPageSize = new PropertyAdapter(preferences, UserPreferences.PROP_PAGE_SIZE, true);
        paPageSize.addPropertyChangeListener(new PageSizeListener());

        feedDisplay = new CompositeFeedDisplay(htmlConfig, imageConfig, pageModel, pageCountModel);
        feedDisplay.setPageSize(preferences.getPageSize());

        // Setup data-adapter
        FeedDisplayAdapter adapter = new FeedDisplayAdapter(feedDisplay);
        GlobalController.SINGLETON.addControllerListener(adapter);

        // Create scroll pane and put list in it
        JScrollPane listSP = new JumplessScrollPane(feedDisplay.getComponent());
        listSP.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        listSP.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        listSP.setFocusable(false);
        listSP.setBorder(null);

        // Register viewport to enable correct scrolling
        feedDisplay.setViewport(listSP.getViewport());

        JPanel content = new JPanel(new BorderLayout());
        content.add(new PagingPanel(pageModel, pageCountModel), BorderLayout.NORTH);
        content.add(listSP, BorderLayout.CENTER);
       
        // Register scroll pane
        setContent(content);

        setFeedTitle(null);
    }

    /**
     * Returns articles list component.
     *
     * @return articles list.
     */
    public IFeedDisplay getFeedView()
    {
        return feedDisplay;
    }

    /**
     * Creates a sub-toolbar with two models.
     *
     * @return sub-toolbar.
     */
    private JToolBar createSubtoolbar()
    {
        final JToolBar toolbar = new JToolBar();
        toolbar.setRollover(true);
        toolbar.setAlignmentY(0.0f);
        toolbar.setOpaque(false);
        toolbar.setBorder(null);
        toolbar.setBorderPainted(false);

        ToolBarBuilder subTBbldr = new ToolBarBuilder(toolbar);

        final JComboBox comboBox = new JComboBox();

        // Indexes of items in this list should correspond to the values of
        // filter setting from FeedRenderingSettings class (FILTER_XYZ constants)
        createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_ALL_TB);
        createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_UNREAD_TB);
        createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_PINNED_TB);

        if (SentimentsFeature.isAvailable())
        {
            createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_POSITIVE_TB);
            createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_NEGATIVE_TB);
            createNAddComboBoxAction(comboBox, ActionsTable.CMD_ARTICLE_SHOW_NON_NEGATIVE_TB);
        }

        int filter = Math.min(RenderingManager.getArticleFilter(), comboBox.getItemCount() - 1);
        comboBox.addActionListener(JComboBoxActionItem.getComboBoxListener());
        comboBox.setOpaque(!SystemUtils.IS_OS_MAC);
        comboBox.setFocusable(false);
        comboBox.setSelectedIndex(filter);

        // Listen to changes of FILTER property and update the selection
        RenderingManager.addPropertyChangeListener(RenderingSettingsNames.ARTICLE_FILTER,
            new PropertyChangeListener()
        {
            public void propertyChange(PropertyChangeEvent evt)
            {
                comboBox.setSelectedIndex(RenderingManager.getArticleFilter());
            }
        });

        JPanel comboboxPanel = new JPanel(new FormLayout("10px, p", SystemUtils.IS_OS_MAC ? "1px, p" : "0, 20px"));
        CellConstraints cc = new CellConstraints();
        comboboxPanel.add(comboBox, cc.xy(2, 2));

        // Mac OS Aqua look has a bug with JComboBox sizing depending on the font size
        // The report: http://lists.apple.com/archives/Java-dev/2005/Jan/msg00510.html
        //   and the answer: http://lists.apple.com/archives/Java-dev/2005/Jan/msg00511.html
        //
        // The page with screenshots of how the Quaqua library deals with the JComboBox
        // look through the custom component look painting (not a native component):
        // http://www.randelshofer.ch/quaqua/guide/jcombobox.html

        if (!SystemUtils.IS_OS_MAC)
        {
            comboBox.setFont(new Font("Tahoma", Font.PLAIN, 10));
        }

        comboboxPanel.setOpaque(false);
       
        subTBbldr.add(comboboxPanel);
        subTBbldr.addGap();
        subTBbldr.add(new ViewModeSelector(GlobalModel.SINGLETON.getViewModeValueModel()));

        return toolbar;
    }

    private void createNAddComboBoxAction(JComboBox box, String cmdcode)
    {
        JToggleButton newitem = new JComboBoxActionItem((ToggleAction)ActionManager.get(cmdcode));
        box.addItem(newitem);
    }

    /**
     * Called when the theme changes.
     *
     * @param evt event object.
     */
    public void propertyChange(PropertyChangeEvent evt)
    {
        updateUI();
    }

    // Changes title text.
    private void setFeedTitle(final IFeed feed)
    {
        String text = (feed == null ? Strings.message("panel.articles.no.feed.selected") : feed.getTitle());
        if (text == null) text = Strings.message("untitled");

        setSubtitle(MessageFormat.format(Strings.message("panel.in"), text));
    }

    /**
     * Listens for <code>GlobalController</code> events in order to get when channel selected. This
     * information is necessary to set correct articles list title.
     */
    private final class ControllerListener extends ControllerAdapter implements IFeedListener
    {
        private IFeed selected;

        /**
         * Invoked after application changes the feed.
         *
         * @param feed feed to which we are switching.
         */
        public void feedSelected(final IFeed feed)
        {
            if (feed != selected)
            {
                if (selected != null) selected.removeListener(this);
                selected = feed;
                if (selected != null) selected.addListener(this);

                // Set the first page
                pageModel.setValue(0);

                setFeedTitle(selected);
            }
        }

        /**
         * Invoked when new article has been added to the feed.
         *
         * @param feed    feed.
         * @param article article.
         */
        public void articleAdded(IFeed feed, IArticle article)
        {
        }

        /**
         * Invoked when the article has been removed from the feed.
         *
         * @param feed    feed.
         * @param article article.
         */
        public void articleRemoved(IFeed feed, IArticle article)
        {
        }

        /**
         * Invoked when the property of the feed has been changed.
         *
         * @param feed     feed.
         * @param property property of the feed.
         * @param oldValue old property value.
         * @param newValue new property value.
         */
        public void propertyChanged(final IFeed feed, String property, Object oldValue, Object newValue)
        {
            if (property.equals(IFeed.PROP_TITLE))
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        setFeedTitle(feed);
                    }
                });
            }
        }
    }

    /**
     * Listener of property changes in article view.
     */
    private class ArticleViewChangeHandler implements PropertyChangeListener
    {
        /**
         * Repaints sub-toolbar on any changes.
         *
         * @param e property change event object.
         */
        public void propertyChange(PropertyChangeEvent e)
        {
            subToolBar.repaint();
        }
    }

    /**
     * Looks at the page model and notifies the feed display on changes in page number.
     */
    private class PageModelListener implements PropertyChangeListener
    {
        /**
         * Invoked when the page number changes.
         *
         * @param evt event.
         */
        public void propertyChange(PropertyChangeEvent evt)
        {
            feedDisplay.setPage((Integer)evt.getNewValue());
        }
    }

    /**
     * Looks at the page size model.
     */
    private class PageSizeListener implements PropertyChangeListener
    {
        /**
         * Invoked when the page number changes.
         *
         * @param evt event.
         */
        public void propertyChange(PropertyChangeEvent evt)
        {
            if (PropertyAdapter.PROPERTYNAME_VALUE.equals(evt.getPropertyName()))
            {
                feedDisplay.setPageSize((Integer)evt.getNewValue());
            }
        }
    }

    /**
     * Paging panel that comes out when the paging is available.
     */
    private class PagingPanel extends JPanel implements PropertyChangeListener
    {
        private final ValueModel pageModel;
        private final ValueModel pageCountModel;
        private JLabel lbInfo;

        /**
         * Creates the panel.
         *
         * @param pageModel         page number model.
         * @param pageCountModel    page count model.
         */
        public PagingPanel(ValueModel pageModel, ValueModel pageCountModel)
        {
            this.pageModel = pageModel;
            this.pageCountModel = pageCountModel;

            lbInfo = new JLabel();
            RenderingManager.addPropertyChangeListener(RenderingSettingsNames.THEME, this);
            PagingControl paging = new PagingControl(pageModel, pageCountModel);

            setLayout(new FormLayout("4dlu, p, 7dlu:grow, p, 4dlu", "2dlu, p, 2dlu"));

            CellConstraints cc = new CellConstraints();
            add(lbInfo, cc.xy(2, 2));
            add(paging, cc.xy(4, 2));

            // Bind the panel
            pageModel.addValueChangeListener(this);
            pageCountModel.addValueChangeListener(this);

            onPageConfigChange();
            onThemeChange();

            enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
        }

        /**
         * Updates the fonts and colors.
         */
        private void onThemeChange()
        {
            lbInfo.setFont(RenderingManager.getArticleTitleFont());
            setBackground(Color.decode("#9cc9ff"));
        }

        /**
         * Updates the text of the info.
         */
        private void onPageConfigChange()
        {
            int pages = (Integer)pageCountModel.getValue();

            setVisible(pages > 1);

            String[] msgs = Strings.slices("pagination.page.of");
            lbInfo.setText(msgs[0] + " " + ((Integer)pageModel.getValue() + 1) + " " + msgs[1] + " " + pages);
        }

        /**
         * Invoked when the page number of the number of pages changes.
         *
         * @param evt event.
         */
        public void propertyChange(PropertyChangeEvent evt)
        {
            String prop = evt.getPropertyName();
            if (ValueHolder.PROPERTYNAME_VALUE.equals(prop))
            {
                onPageConfigChange();
            } else if (RenderingSettingsNames.THEME.equals(prop))
            {
                onThemeChange();
            }
        }

        @Override
        protected void processMouseWheelEvent(MouseWheelEvent e)
        {
            feedDisplay.getComponent().dispatchEvent(e);
        }
    }
}
TOP

Related Classes of com.salas.bb.views.ArticleListPanel$PagingPanel

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.