/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ro.nextreports.designer.util;
import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.PopupMenuListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.PopupMenuEvent;
import ro.nextreports.designer.ui.MagicButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ContainerListener;
import java.awt.event.ContainerEvent;
import java.awt.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.List;
import java.util.ArrayList;
/**
* User: mihai.panaitescu
* Date: 07-Jan-2010
* Time: 13:07:10
*/
public class DropDownListButton extends MagicButton implements
ChangeListener, PopupMenuListener, ActionListener,
PropertyChangeListener {
private final JButton mainButton = this;
private final JButton arrowButton = new JButton(ImageUtil.getImageIcon("dropdown"));
private boolean popupVisible = false;
private JPopupMenu popupMenu;
public DropDownListButton() {
mainButton.getModel().addChangeListener(this);
arrowButton.getModel().addChangeListener(this);
arrowButton.addActionListener(this);
mainButton.addPropertyChangeListener("enabled", this); // NOI18N
getPopupMenu().addContainerListener(new MenuContainerListener());
}
public DropDownListButton(String text) {
this();
setText(text);
}
public void propertyChange(PropertyChangeEvent event) {
arrowButton.setEnabled(mainButton.isEnabled());
}
public void stateChanged(ChangeEvent event) {
if (event.getSource() == mainButton.getModel()) {
if (popupVisible && !mainButton.getModel().isRollover()) {
mainButton.getModel().setRollover(true);
return;
}
arrowButton.getModel().setRollover(mainButton.getModel().isRollover());
arrowButton.setSelected(mainButton.getModel().isArmed()
&& mainButton.getModel().isPressed());
} else {
if (popupVisible && !arrowButton.getModel().isSelected()) {
arrowButton.getModel().setSelected(true);
return;
}
mainButton.getModel().setRollover(arrowButton.getModel().isRollover());
}
}
public void actionPerformed(ActionEvent event) {
JPopupMenu popup = getPopupMenu();
popup.addPopupMenuListener(this);
int position = 0;
if (mainButton.getWidth() + arrowButton.getWidth() > popup.getPreferredSize().getWidth()) {
position = mainButton.getWidth() + arrowButton.getWidth() - (int)popup.getPreferredSize().getWidth();
}
popup.show(mainButton, position, mainButton.getHeight());
}
public void popupMenuWillBecomeVisible(PopupMenuEvent event) {
popupVisible = true;
mainButton.getModel().setRollover(true);
arrowButton.getModel().setSelected(true);
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent event) {
popupVisible = false;
mainButton.getModel().setRollover(false);
arrowButton.getModel().setSelected(false);
((JPopupMenu) event.getSource()).removePopupMenuListener(this);
}
public void popupMenuCanceled(PopupMenuEvent event) {
popupVisible = false;
}
private JPopupMenu getPopupMenu() {
if (popupMenu == null) {
popupMenu = new JPopupMenu();
}
return popupMenu;
}
public void setItems(List<String> items) {
List<Boolean> marked = new ArrayList<Boolean>();
for (String item : items) {
marked.add(Boolean.FALSE);
}
setItems(items, marked);
}
public void setItems(List<String> items, List<Boolean> marked) {
if ((items == null) || (marked == null) || (items.size() != marked.size())) {
throw new IllegalArgumentException("items and marked must have the same size");
}
popupMenu = null;
for (int i=0, size=items.size(); i<size; i++) {
ItemAction action = new ItemAction(items.get(i), marked.get(i));
JMenuItem mi = getPopupMenu().add(action);
if (action.getMarked()) {
mi.setForeground(Color.LIGHT_GRAY);
}
}
}
class ItemAction extends AbstractAction {
private String item;
private Boolean marked;
public ItemAction(String item, Boolean marked) {
this.item = item;
this.marked = marked;
putValue(NAME, item);
}
public void actionPerformed(ActionEvent e) {
mainButton.setText(getText(item));
afterSelection(item, marked);
}
public Boolean getMarked() {
return marked;
}
}
protected String getText(String item) {
return item;
}
protected void afterSelection(String item, Boolean marked) {
}
public class MenuContainerListener implements ContainerListener {
MenuActionListener menuActionListener;
public MenuContainerListener() {
menuActionListener = new MenuActionListener();
}
public void componentAdded(ContainerEvent e) {
((AbstractButton) e.getChild()).addActionListener(menuActionListener);
}
public void componentRemoved(ContainerEvent e) {
((AbstractButton) e.getChild()).removeActionListener(menuActionListener);
}
}
private class MenuActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
AbstractButton source = (AbstractButton) e.getSource();
mainButton.setAction(source.getAction());
}
}
public JPanel getPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(this);
panel.add(arrowButton);
return panel;
}
public void setMinimumSize(Dimension minimumSize) {
super.setMinimumSize(minimumSize);
arrowButton.setMinimumSize(new Dimension((int)arrowButton.getPreferredSize().getWidth(), (int)minimumSize.getHeight()));
}
public void setMaximumSize(Dimension maximumSize) {
super.setMaximumSize(maximumSize);
arrowButton.setMaximumSize(new Dimension((int)arrowButton.getPreferredSize().getWidth(), (int)maximumSize.getHeight()));
}
public void setPreferredSize(Dimension preferredSize) {
super.setPreferredSize(preferredSize);
arrowButton.setMaximumSize(new Dimension((int)arrowButton.getPreferredSize().getWidth(), (int)preferredSize.getHeight()));
}
public void setArrowTooltip(String tooltip) {
arrowButton.setToolTipText(tooltip);
}
}