/******************************************************************************* * Copyright (c) 2014 Open Door Logistics (www.opendoorlogistics.com) * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v3 * which accompanies this distribution, and is available at http://www.gnu.org/licenses/lgpl.txt ******************************************************************************/ package com.opendoorlogistics.studio.controls; import java.awt.Component; import java.awt.Font; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.swing.ComboBoxEditor; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import com.opendoorlogistics.codefromweb.BottomLineBorder; import com.opendoorlogistics.codefromweb.BoundsPopupMenuListener; import com.opendoorlogistics.core.utils.strings.Strings; public abstract class DynamicComboBox<T> extends EditableComboBox<T> { private static Font firstLineFont = new Font(Font.SANS_SERIF, Font.BOLD | Font.ITALIC,12); public DynamicComboBox(T initialValue, boolean addPopupListener, boolean editable) { setEditable(editable); // fill in a non-empty initial value if needed if (Strings.isEmpty(initialValue)) { List<T> available = getAvailableItems(); if (available != null && available.size() > 0 && available.get(0)!=null && Strings.isEmpty(available.get(0).toString()) == false) { initialValue = available.get(0); } } if(isEditable()){ getEditor().setItem(initialValue); } // Initialise listeners ensuring called in correct order, so bounds popup only // called after updating the items... BoundsPopupMenuListener bpml = new BoundsPopupMenuListener(true,false); if (addPopupListener) { addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(PopupMenuEvent e) { updateMenu(); bpml.popupMenuWillBecomeVisible(e); // ComboBoxWithWiderPopup.adjustPopupWidth(DynamicComboBox.this, null); } @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { bpml.popupMenuWillBecomeInvisible(e); } @Override public void popupMenuCanceled(PopupMenuEvent e) { bpml.popupMenuCanceled(e); } }); }else{ addPopupMenuListener(bpml); } final JLabel firstLine = new JLabel(); firstLine.setBorder(new BottomLineBorder()); firstLine.setFont(firstLineFont); //firstLine.setForeground(new Color(0, 0, 100)); // Font.SANS_SERIF // Font f; // firstLine.getFont(). final JLabel laterLines = new JLabel(); setRenderer(new ListCellRenderer<T>() { @Override public Component getListCellRendererComponent(JList<? extends T> list, T value, int index, boolean isSelected, boolean cellHasFocus) { JLabel label = index == 0 ? firstLine : laterLines; setLabelText(value, label); label.setBackground(isSelected ? list.getSelectionBackground() : list.getBackground()); label.setForeground(isSelected ? list.getSelectionForeground() : list.getForeground()); label.setOpaque(true); return label; } }); } protected abstract List<T> getAvailableItems(); public void updateMenu() { ComboBoxEditor editor = getEditor(); Object value =editor.getItem(); removeAllItems(); if(isEditable()){ if (value != null) { addItem((T)value); setSelectedIndex(0); } } List<T> items = getAvailableItems(); if (items != null) { for (T field : items) { // if (value == null || value.toString().equals(field) == false) { addItem(field); // } } } } /** * Null-pointer safe version of asList * @param vals * @return */ protected List<T> asList(T [] vals){ if(vals==null){ return new ArrayList<>(); } return Arrays.asList(vals); } public T getValue(){ return (T)getEditor().getItem(); } /** * Override this to control the text shown for a value * @param value * @param label */ protected void setLabelText (T value, JLabel label) { label.setText(value!=null? value.toString():""); } }