All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alee.laf.combobox.ComboBoxPainter Maven / Gradle / Ivy

There is a newer version: 1.2.14
Show newest version
package com.alee.laf.combobox;

import com.alee.api.jdk.Objects;
import com.alee.laf.WebLookAndFeel;
import com.alee.managers.language.Language;
import com.alee.managers.language.LanguageListener;
import com.alee.managers.language.LanguageSensitive;
import com.alee.managers.language.UILanguageManager;
import com.alee.painter.decoration.AbstractDecorationPainter;
import com.alee.painter.decoration.DecorationState;
import com.alee.painter.decoration.IDecoration;
import com.alee.utils.swing.EditabilityListener;
import com.alee.utils.swing.VisibilityListener;

import javax.swing.*;
import java.awt.*;
import java.util.List;

/**
 * Basic painter for {@link JComboBox} component.
 * It is used as {@link WebComboBoxUI} default painter.
 *
 * @param  component type
 * @param  component UI type
 * @param  decoration type
 * @author Alexandr Zernov
 */
public class ComboBoxPainter>
        extends AbstractDecorationPainter implements IComboBoxPainter, EditabilityListener, VisibilityListener
{
    /**
     * Listeners.
     */
    protected transient LanguageListener languageSensitive;

    /**
     * Painting variables.
     */
    protected transient CellRendererPane currentValuePane = null;

    @Override
    protected void installPropertiesAndListeners ()
    {
        super.installPropertiesAndListeners ();
        installComboBoxListeners ();
        installLanguageListeners ();
    }

    @Override
    protected void uninstallPropertiesAndListeners ()
    {
        uninstallLanguageListeners ();
        uninstallComboBoxListeners ();
        super.uninstallPropertiesAndListeners ();
    }

    @Override
    protected void propertyChanged ( final String property, final Object oldValue, final Object newValue )
    {
        // Perform basic actions on property changes
        super.propertyChanged ( property, oldValue, newValue );

        // Updating combobox popup list state
        // This is a workaround to allow box renderer properly inherit enabled state
        if ( Objects.equals ( property, WebLookAndFeel.ENABLED_PROPERTY ) )
        {
            ui.getListBox ().setEnabled ( component.isEnabled () );
        }
    }

    /**
     * Installs combobox listeners that update decoration states.
     */
    protected void installComboBoxListeners ()
    {
        ui.addEditabilityListener ( this );
        ui.addPopupVisibilityListener ( this );
    }

    @Override
    public void editabilityChanged ( final boolean editable )
    {
        updateDecorationState ();
    }

    @Override
    public void visibilityChanged ( final boolean visible )
    {
        updateDecorationState ();
    }

    /**
     * Uninstalls combobox listeners that update decoration states.
     */
    protected void uninstallComboBoxListeners ()
    {
        ui.removePopupVisibilityListener ( this );
        ui.removeEditabilityListener ( this );
    }

    /**
     * Installs language listeners.
     */
    protected void installLanguageListeners ()
    {
        languageSensitive = new LanguageListener ()
        {
            @Override
            public void languageChanged ( final Language oldLanguage, final Language newLanguage )
            {
                if ( isLanguageSensitive () )
                {
                    // Updating sizes according to renderer changes
                    ui.updateRendererSize ();
                }
            }
        };
        UILanguageManager.addLanguageListener ( component, languageSensitive );
    }

    /**
     * Returns whether or not table is language-sensitive.
     *
     * @return {@code true} if table is language-sensitive, {@code false} otherwise
     */
    protected boolean isLanguageSensitive ()
    {
        boolean sensitive = false;
        if ( component instanceof LanguageSensitive ||
                component.getRenderer () instanceof LanguageSensitive )
        {
            // Either table header or its default renderer is language-sensitive
            sensitive = true;
        }
        else
        {
            // Checking existing combobox items for being language-sensitive
            final ListModel model = component.getModel ();
            for ( int i = 0; i < model.getSize (); i++ )
            {
                if ( model.getElementAt ( i ) instanceof LanguageSensitive )
                {
                    sensitive = true;
                    break;
                }
            }
        }
        return sensitive;
    }

    /**
     * Uninstalls language listeners.
     */
    protected void uninstallLanguageListeners ()
    {
        UILanguageManager.removeLanguageListener ( component, languageSensitive );
        languageSensitive = null;
    }

    @Override
    public List getDecorationStates ()
    {
        final List states = super.getDecorationStates ();
        if ( component.isEditable () )
        {
            states.add ( DecorationState.editable );
        }
        states.add ( ui.isPopupVisible ( component ) ? DecorationState.expanded : DecorationState.collapsed );
        return states;
    }

    @Override
    public void prepareToPaint ( final CellRendererPane currentValuePane )
    {
        this.currentValuePane = currentValuePane;
    }

    @Override
    protected void paintContent ( final Graphics2D g2d, final Rectangle bounds, final C c, final U ui )
    {
        // Selected non-editable value
        paintCurrentValue ( g2d, ui.getValueBounds () );

        // Cleaning up paint variables
        cleanupAfterPaint ();
    }

    /**
     * Method called when single paint operation is completed.
     */
    protected void cleanupAfterPaint ()
    {
        this.currentValuePane = null;
    }

    /**
     * Paints the currently selected item.
     *
     * @param g2d    graphics context
     * @param bounds bounds
     */
    protected void paintCurrentValue ( final Graphics2D g2d, final Rectangle bounds )
    {
        if ( !component.isEditable () )
        {
            // Retrieving configured renderer
            final JList list = ui.getListBox ();
            final Object value = component.getSelectedItem ();
            final boolean selected = !component.isPopupVisible ();
            final boolean isFocused = isFocused ();
            final ListCellRenderer renderer = component.getRenderer ();
            final Component c = renderer.getListCellRendererComponent ( list, value, -1, selected, isFocused );

            // Updating combobox-related renderer settings
            c.setFont ( component.getFont () );

            // Painting current value
            final int x = bounds.x;
            final int y = bounds.y;
            final int w = bounds.width;
            final int h = bounds.height;
            final boolean shouldValidate = c instanceof JPanel;
            currentValuePane.paintComponent ( g2d, c, component, x, y, w, h, shouldValidate );
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy