alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 Sun Public License Notice
 * 
 * The contents of this file are subject to the Sun Public License
 * Version 1.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://www.sun.com/
 * 
 * The Original Code is NetBeans. The Initial Developer of the Original
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
 * Microsystems, Inc. All Rights Reserved.
 *//*
 * RadioInplaceEditor.java
 *
 * Created on 28 September 2003, 01:41
 */

package org.openide.explorer.propertysheet;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyEditor;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import org.openide.util.WeakSet;

/** An inplace editor that represents the contents of a property editor's
 * getTags() method as a set of radio buttons.  For larger sets of choices
 * it is preferable to use a combo box, but for situations where only 3 to 5
 * options are available, this is preferable.
 *
 * @author  Tim Boudreau
 */
class RadioInplaceEditor extends JPanel implements InplaceEditor,
                                                         ActionListener {
    private transient List actionListenerList;
    protected transient PropertyEditor editor=null;
    protected transient PropertyEnv env = null;
    protected transient PropertyModel mdl=null;
    protected transient ButtonGroup group=null;

    private boolean tableUI=false;
    public RadioInplaceEditor(boolean tableUI) {
        setLayout(new AutoGridLayout(false));
        this.tableUI=tableUI;
        setOpaque(true);
    }

    public void clear() {
        editor=null;
        env=null;
        mdl=null;
        group=null;
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            if (c[i] instanceof JRadioButton) {
                ((JRadioButton) c[i]).removeActionListener(this);
            }
        }
        removeAll();
        setEnabled(true);
    }
    
    /** Overridden to avoid grabbing the AWT tree lock */
    public Dimension getPreferredSize() {
        if (getLayout() != null) {
            return getLayout().preferredLayoutSize(this);
        } else {
            return super.getPreferredSize();
        }
    }
    
    boolean isFirstEvent=false;
    public void addNotify() {
        super.addNotify();
        isFirstEvent=true;
    }
    
    private WeakSet buttonCache = new WeakSet();
    private InvRadioButton[] getButtons(int count) {
        InvRadioButton[] result = new InvRadioButton[count];

        Iterator i = buttonCache.iterator();
        int idx=0;
        while (i.hasNext() && idx < count) {
            result[idx] = (InvRadioButton) i.next();
            if (result[idx] != null) {
                result[idx].setEnabled(true);
                result[idx].setSelected(false);
                idx++;
            }
        }
        for (;idx < count; idx++) {
            result[idx] = createButton();
            buttonCache.add(result[idx]);
        }
        return result;  
    }
    
    public void setEnabled(boolean val) {
//        System.err.println("RadioEditor.setEnabled " + val);
        super.setEnabled(val);
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            c[i].setEnabled(val);
        }
    }
    
    public void setBackground(Color col) {
        super.setBackground(col);
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            c[i].setBackground(col);
        }
    }
    
    public void setForeground(Color col) {
        super.setForeground(col);
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            c[i].setForeground(col);
        }
    }
    
    /** In 1.4, panels can and will receive focus; if we define our own
     * focus policy, we're responsible for all possible subcomponents.
     * Therfore just proxy requestFocusInWindow for the selected radio
     * button  */
    public void requestFocus() {
        Component[] c = getComponents();
        if (c.length > 0) {
            for (int i=0; i < c.length; i++) {
                if (c[i] instanceof InvRadioButton 
                && ((InvRadioButton) c[i]).isSelected()) {
                    c[i].requestFocus();
                    return;
                }
            }
            c[0].requestFocus();
        } else {
            super.requestFocus();
        }
    }
    
    public boolean requestFocusInWindow() {
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            if (c[i] instanceof InvRadioButton 
            && ((InvRadioButton) c[i]).isSelected()) {
                return c[i].requestFocusInWindow();
            }
        }
        return super.requestFocusInWindow();
    }
    
    private boolean useTitle=false;
    public void setUseTitle(boolean val) {
        if (useTitle != val) {
            useTitle = val;
            if (env != null) {
                setBorder (new TitledBorder(
                    env.getFeatureDescriptor().getDisplayName()));
            }
        }
    }    

    public void connect(PropertyEditor pe, PropertyEnv env) {
        if (!tableUI && env != null && useTitle) {
           setBorder (new TitledBorder(env.getFeatureDescriptor().getDisplayName()));
        } else {
            setBorder(null);
        }
        editor = pe;
        String[] tags = editor.getTags();
        group = new ButtonGroup();
        InvRadioButton[] buttons=getButtons(tags.length);

        if (env != null) {
            setEnabled (env.isEditable());
        }
        
        for (int i=0; i < tags.length; i++) {
            InvRadioButton jr = buttons[i];
            configureButton (jr, tags[i]);
            add(jr);
        }
    }
    
    /** Renderer version overrides this to create a subclass that won't
     * fire changes */
    protected InvRadioButton createButton() {
        return new InvRadioButton();
    }
    
    /** Renderer version overrides this */
    protected void configureButton (InvRadioButton ire, String txt) {
        ire.addActionListener(this);
        if (editor.getTags().length == 1) {
            ire.setEnabled(false);
        } else {
            ire.setEnabled(isEnabled());
        }
        if (tableUI) {
            ire.setFocusable(false);
        } else {
            ire.setFocusable(true);
        }
        ire.setText(txt);
        if (txt.equals(editor.getAsText())) {
            ire.setSelected(true);
        } else {
            ire.setSelected(false);
        }
        ire.setFont(getFont());
        ire.setBackground(getBackground());
        ire.setForeground(getForeground());
        group.add(ire);
    }

    public JComponent getComponent() {
        return this;
    }

    public KeyStroke[] getKeyStrokes() {
        return null;
    }

    public PropertyEditor getPropertyEditor() {
        return editor;
    }

    public PropertyModel getPropertyModel() {
        return mdl;
    }

    public Object getValue() {
        Component[] c = getComponents();
//        System.out.println("GetSelection is " + group.getSelection());
        for (int i=0; i < c.length; i++) {
            if (c[i] instanceof JRadioButton) {
                if (group.getSelection() == ((JRadioButton) c[i]).getModel()) {
                    String result = ((JRadioButton) c[i]).getText();
                    return result;
                }
            }
        }
        return null;
    }

    public void handleInitialInputEvent(InputEvent e) {
        System.err.println("HandleInitialInputEvent");
        getLayout().layoutContainer(this);
        if (e instanceof MouseEvent) {
            Point p = SwingUtilities.convertPoint(
                (JComponent)e.getSource(), ((MouseEvent) e).getPoint(), this);
            Component c = getComponentAt(p);
            
            if (c instanceof JRadioButton) {
                ((JRadioButton) c).setSelected(true);
                c.requestFocus();
                fireActionPerformed(new ActionEvent(this, 
			ActionEvent.ACTION_PERFORMED, InplaceEditor.COMMAND_SUCCESS));
            }
        } else {
            Component[] c = getComponents();
            for (int i=0; i < c.length; i++) {
                if (c[i] instanceof JRadioButton) {
                    if (((JRadioButton) c[i]).isSelected()) {
                        c[i].requestFocusInWindow();
                    }
                }
            }
        }
    }

    public boolean isKnownComponent(Component c) {
        return c!=null && (c == this || c instanceof InvRadioButton);
    }

    public void reset() {
        setValue(editor.getAsText());
    }

    public void setPropertyModel(PropertyModel pm) {
        mdl = pm;
    }

    public void setValue(Object o) {
        Component[] c = getComponents();
        for (int i=0; i < c.length; i++) {
            if (c[i] instanceof JRadioButton) {
                if (((JRadioButton)c[i]).getText().equals(o)) {
                    ((JRadioButton)c[i]).setSelected(true);
                } else {
                    //Necessary for renderer, its buttons don't fire changes
                    ((JRadioButton)c[i]).setSelected(false);
                }
            }
        }
    }
    
    public boolean supportsTextEntry() {
        return false;
    }

    public synchronized void addActionListener(java.awt.event.ActionListener listener) {
        if (actionListenerList == null ) {
            actionListenerList = new java.util.ArrayList();
        }
        actionListenerList.add(listener);
    }

    public synchronized void removeActionListener(java.awt.event.ActionListener listener) {
        if (actionListenerList != null ) {
            actionListenerList.remove(listener);
        }
    }

    private void fireActionPerformed(final java.awt.event.ActionEvent event) {
//        System.err.println("Radio editor firing action performed " + event.getActionCommand());
        java.util.List list;
        synchronized (this) {
            if (actionListenerList == null) return;
            list = (List)((ArrayList)actionListenerList).clone();
        }
        final java.util.List theList = list;
        //When used in a table, the typical case is that the editor is instantiated,
        //processes its mouse event, fires an event and is immediately removed.
        //Using invokeLater allows the table to repaint appropriately for selection,
        //etc, reducing flicker.
        if (tableUI) {
            SwingUtilities.invokeLater (new Runnable() {
                public void run() {
                    for (int i = 0; i < theList.size(); i++) {
                        ((java.awt.event.ActionListener)theList.get(i)).actionPerformed(event);
                    }
                }
            });
        } else {
            for (int i = 0; i < list.size(); i++) {
                ((java.awt.event.ActionListener)theList.get(i)).actionPerformed(event);
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        ActionEvent ae = new ActionEvent(this, 
            ActionEvent.ACTION_PERFORMED, InplaceEditor.COMMAND_SUCCESS);
        fireActionPerformed(ae);
    }

    
    public void paint (Graphics g) {
        if (isShowing()) {
            super.paint(g);
        } else {
            getLayout().layoutContainer(this);
            Component[] c = getComponents();
            Color col = g.getColor();
            try {
                g.setColor(getBackground());
                g.fillRect(0,0, getWidth(),getHeight());
                    for (int i=0; i < c.length; i++) {
                        Rectangle r = c[i].getBounds();
                        if (g.hitClip(r.x, r.y,r.width,r.height)) {
                            Graphics g2 = g.create(r.x, r.y, r.width, r.height);
                            try {
                                c[i].paint(g2);
                            } finally {
                                g2.dispose();
                            }
                        }
                    }
                if (getBorder() != null) {
                    super.paintBorder(g);
                }
            } finally {
                g.setColor(col);
            }
        }
    }
     
    public void processMouseEvent(MouseEvent me) {
        if (isFirstEvent) {
            handleInitialInputEvent(me);
            isFirstEvent=false;
        } else {
            super.processMouseEvent(me);
        }
    }
    
    public Component getComponentAt(int x, int y) {
        getLayout().layoutContainer(this);
        Component result = super.getComponentAt(x,y);
        System.err.println("getComponentAt " + x + "," + y + " returning " + result.getName());
        return result;
    }
    
    /** A JRadioButton that can calculate its preferred size when it
     * has no parent */
    class InvRadioButton extends JRadioButton {
        public InvRadioButton () {
            super ();
        }
        
        public String getName() {
            return "InvRadioButton - " + getText(); //NOI18N
        }
        
        public void processKeyEvent(java.awt.event.KeyEvent ke) {
            super.processKeyEvent(ke);
            if ((ke.getKeyCode() == ke.VK_ENTER || ke.getKeyCode() == ke.VK_ESCAPE) 
                && ke.getID() == ke.KEY_PRESSED) {

                RadioInplaceEditor.this.fireActionPerformed(new ActionEvent(this, 
                    ActionEvent.ACTION_PERFORMED, 
                    ke.getKeyCode() == ke.VK_ENTER ? COMMAND_SUCCESS : 
                        COMMAND_FAILURE));
            }
        }
        
        public Dimension getPreferredSize() {
            int w = 0;
            int h = 0;
            Graphics g = PropUtils.getScratchGraphics(this);
            FontMetrics fm = g.getFontMetrics(getFont());
            if (getIcon() != null) {
                w = getIcon().getIconWidth();
                h = getIcon().getIconHeight();
            }
            if (getBorder() != null) {
                Insets ins = getBorder().getBorderInsets(this);
                w+=ins.left + ins.right;
                h+=ins.bottom+ins.top;
            }
            w += fm.stringWidth(getText()) + 22;
            h = Math.max(fm.getHeight(), h) + 2;
            return new Dimension(w,h);
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.