001: /*
002: * Copyright (C) 2004 NNL Technology AB
003: * Visit www.infonode.net for information about InfoNode(R)
004: * products and how to contact NNL Technology AB.
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or (at your option) any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
019: * MA 02111-1307, USA.
020: */
021:
022: // $Id: PopupList.java,v 1.13 2005/06/29 11:57:40 johan Exp $
023: package net.infonode.gui;
024:
025: import net.infonode.gui.panel.SimplePanel;
026:
027: import javax.swing.*;
028: import javax.swing.border.LineBorder;
029: import javax.swing.event.ListSelectionEvent;
030: import javax.swing.event.ListSelectionListener;
031: import javax.swing.event.PopupMenuEvent;
032: import javax.swing.event.PopupMenuListener;
033: import java.awt.*;
034: import java.awt.event.*;
035: import java.util.ArrayList;
036:
037: public class PopupList extends SimplePanel {
038: private class PopupButtonModel extends DefaultButtonModel {
039: private boolean pressed;
040:
041: public boolean isPressed() {
042: return super .isPressed() || pressed;
043: }
044:
045: public boolean isArmed() {
046: return super .isArmed() || pressed;
047: }
048:
049: public void setPressedInternal(boolean pressed) {
050: this .pressed = pressed;
051: fireStateChanged();
052: }
053: }
054:
055: private class Popup extends JPopupMenu {
056: private JList list = new JList();
057: private JScrollPane scrollPane = new JScrollPane(list,
058: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
059: JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
060: private int oldIndex;
061:
062: Popup() {
063: setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
064: scrollPane.setBorder(null);
065: setBorderPainted(true);
066: setBorder(new LineBorder(UIManagerUtil.getColor(
067: "controlDkShadow", Color.BLACK), 1));
068:
069: add(scrollPane);
070: scrollPane.getViewport().setOpaque(false);
071: list.addListSelectionListener(new ListSelectionListener() {
072: public void valueChanged(ListSelectionEvent e) {
073: if (!e.getValueIsAdjusting())
074: setVisible(false);
075: }
076: });
077:
078: update();
079: }
080:
081: public MouseMotionListener getMouseMotionListener() {
082: return new MouseMotionAdapter() {
083: public void mouseDragged(MouseEvent e) {
084: if (SwingUtilities.isLeftMouseButton(e)) {
085: Component c = (Component) e.getSource();
086: Point p = SwingUtilities.convertPoint(c, e
087: .getPoint(), scrollPane);
088: int index = list.locationToIndex(SwingUtilities
089: .convertPoint(scrollPane, p, list));
090: if (!c.contains(e.getPoint())
091: && (scrollPane.contains(p)
092: || (p.getY() > scrollPane
093: .getY()
094: + scrollPane
095: .getHeight()) || p
096: .getY() < scrollPane.getY())) {
097: list.setSelectedIndex(index);
098: list.ensureIndexIsVisible(index);
099: }
100: }
101: }
102: };
103: }
104:
105: public MouseListener getMouseListener() {
106: return new MouseAdapter() {
107: public void mousePressed(MouseEvent e) {
108: if (SwingUtilities.isLeftMouseButton(e)) {
109: if (isVisible()) {
110: setVisible(false);
111: return;
112: }
113: update();
114: scrollPane.setViewportView(null);
115: list.setValueIsAdjusting(true);
116: fireWillBecomeVisible();
117: list.setVisibleRowCount(Math.min(list
118: .getModel().getSize(), 8));
119: oldIndex = list.getSelectedIndex();
120: list.ensureIndexIsVisible(oldIndex);
121: scrollPane.setViewportView(list);
122: Component c = (Component) e.getSource();
123: show(c, 0, c.getHeight());
124: }
125: }
126:
127: public void mouseReleased(MouseEvent e) {
128: if (SwingUtilities.isLeftMouseButton(e)) {
129: if (!isVisible())
130: return;
131:
132: Point p = SwingUtilities.convertPoint(
133: (Component) e.getSource(),
134: e.getPoint(), scrollPane);
135: if (scrollPane.contains(p)) {
136: list.setValueIsAdjusting(false);
137: } else if (!((Component) e.getSource())
138: .contains(e.getPoint())) {
139: list.setSelectedIndex(oldIndex);
140: list.setValueIsAdjusting(false);
141: }
142: }
143: }
144: };
145: }
146:
147: public JList getList() {
148: return list;
149: }
150:
151: public void updateUI() {
152: super .updateUI();
153: setBorder(new LineBorder(UIManagerUtil.getColor(
154: "controlDkShadow", Color.BLACK), 1));
155: if (list != null)
156: update();
157: }
158:
159: private void update() {
160: /*list.setFont(UIManager.getFont("ComboBox.font"));
161: list.setForeground(UIManagerUtil.getColor("ComboBox.foreground"));
162: list.setBackground(UIManagerUtil.getColor("ComboBox.background", "control"));
163: list.setSelectionForeground(UIManagerUtil.getColor("ComboBox.selectionForeground"));
164: list.setSelectionBackground(UIManagerUtil.getColor("ComboBox.selectionBackground"));
165: list.setBorder(null);*/
166: scrollPane.getViewport().setOpaque(false);
167: scrollPane.setBorder(null);
168: }
169: }
170:
171: private Popup popup = new Popup();
172: private ArrayList listeners = new ArrayList(1);
173:
174: public PopupList(AbstractButton component) {
175: setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
176: setButton(component);
177:
178: popup.addPopupMenuListener(new PopupMenuListener() {
179: public void popupMenuCanceled(PopupMenuEvent e) {
180: }
181:
182: public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
183: ((PopupButtonModel) ((AbstractButton) getComponent(0))
184: .getModel()).setPressedInternal(false);
185: }
186:
187: public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
188: ((PopupButtonModel) ((AbstractButton) getComponent(0))
189: .getModel()).setPressedInternal(true);
190: }
191: });
192: }
193:
194: public JList getList() {
195: return popup.getList();
196: }
197:
198: public void setButton(AbstractButton component) {
199: if (getComponentCount() > 0) {
200: AbstractButton c = (AbstractButton) getComponent(0);
201: c.removeMouseListener(popup.getMouseListener());
202: c.removeMouseMotionListener(popup.getMouseMotionListener());
203: remove(c);
204: }
205:
206: add(component);
207: component.setModel(new PopupButtonModel());
208: component.setAutoscrolls(true);
209: component.setFocusable(false);
210: component.addMouseListener(popup.getMouseListener());
211: component
212: .addMouseMotionListener(popup.getMouseMotionListener());
213: }
214:
215: public AbstractButton getButton() {
216: return getComponentCount() == 0 ? null
217: : (AbstractButton) getComponent(0);
218: }
219:
220: public void updateUI() {
221: super .updateUI();
222: if (popup != null)
223: SwingUtilities.updateComponentTreeUI(popup);
224: }
225:
226: public void addPopupListListener(PopupListListener l) {
227: listeners.add(l);
228: }
229:
230: public void removePopupListListener(PopupListListener l) {
231: listeners.remove(l);
232: }
233:
234: public void addListSelectionListener(ListSelectionListener l) {
235: getList().addListSelectionListener(l);
236: }
237:
238: public void removeListSelectionListener(ListSelectionListener l) {
239: getList().removeListSelectionListener(l);
240: }
241:
242: private void fireWillBecomeVisible() {
243: Object[] l = listeners.toArray();
244: for (int i = 0; i < l.length; i++)
245: ((PopupListListener) l[i]).willBecomeVisible(this);
246: }
247: }
|