import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.*;

/**
 * A ComboBox that correctly renders when used in a table.
 **
 ** @author Nobuo Tamemasa, codeguru.earthweb.com
 */
public class SteppedComboBox extends JComboBox {
	/** The width needed to display the ComboBox's popup window. */
	protected int popupWidth;

	/** Create a ComboBox using the given model. */
	public SteppedComboBox(ComboBoxModel aModel) {
		super(aModel);

		setUI(new SteppedComboBoxUI());

		popupWidth = 0;
	}
// end constructor with a ComboBoxModel

	/** Create a ComboBox using the given array. */
	public SteppedComboBox(final Object[] items) {
		super(items);

		setUI(new SteppedComboBoxUI());

		popupWidth = 0;
	}
// end constructor with an Object array

	/** Create a ComboBox using the given vector. */
	public SteppedComboBox(Vector items) {
		super(items);

		setUI(new SteppedComboBoxUI());

		popupWidth = 0;
	}
// end constructor with a Vector

	/**
	 * Assign the width of this ComboBox for displaying in a popup window.
	 */
	public void setPopupWidth(int width) {
		popupWidth = width;
	}

	/**
	 * Determine the size necessary to display this ComboBox in a popup window.
	 */
	public Dimension getPopupSize() {
		Dimension size = getSize();

		if (popupWidth < 1) {
			popupWidth = size.width;
		}

		return (new Dimension(popupWidth, size.height));
	}
// end method setPopupWidth

	/** The UI for this ComboBox. */
	private class SteppedComboBoxUI extends MetalComboBoxUI {
		/** Draw the ComboBox. */
		protected ComboPopup createPopup() {
			BasicComboPopup popup = new BasicComboPopup(comboBox) {
				public void show() {
					Dimension popupSize = ((SteppedComboBox) comboBox).getPopupSize();
					popupSize.setSize(popupSize.width, getPopupHeightForRowCount(comboBox.getMaximumRowCount()));

					Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, popupSize.width,
							popupSize.height);

					scroller.setMaximumSize(popupBounds.getSize());
					scroller.setPreferredSize(popupBounds.getSize());
					scroller.setMinimumSize(popupBounds.getSize());

					list.invalidate();

					int selectedIndex = comboBox.getSelectedIndex();

					if (selectedIndex == -1) {
						list.clearSelection();
					}

					else {
						list.setSelectedIndex(selectedIndex);
					}

					list.ensureIndexIsVisible(list.getSelectedIndex());

					setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());

					show(comboBox, popupBounds.x, popupBounds.y);
				}
			};

			popup.getAccessibleContext().setAccessibleParent(comboBox);

			return (popup);
		}
	}
}
