/* * Copyright (C) 2011 Jason von Nieda <jason@vonnieda.org> * * This file is part of OpenPnP. * * OpenPnP is free software: you can redistribute it and/or modify it under the terms of the GNU * General Public License as published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * OpenPnP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * Public License for more details. * * You should have received a copy of the GNU General Public License along with OpenPnP. If not, see * <http://www.gnu.org/licenses/>. * * For more information about OpenPnP visit http://openpnp.org */ package org.openpnp.gui.components; import java.awt.Component; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.Vector; import javax.swing.ComboBoxModel; import javax.swing.JComboBox; import javax.swing.JList; import javax.swing.JSeparator; import javax.swing.ListCellRenderer; /** * Class that allows you to add a JSeparator to the ComboBoxModel. * * The separator is rendered as a horizontal line. Using the Up/Down arrow keys will cause the combo * box selection to skip over the separator. If you attempt to select the separator with the mouse, * the selection will be ignored and the drop down will remain open. */ @SuppressWarnings("serial") public class SeparatorComboBox extends JComboBox implements KeyListener { // Track key presses and releases private boolean released = true; // Track when the separator has been selected private boolean separatorSelected = false; /** * Standard constructor. See JComboBox API for details */ public SeparatorComboBox() { super(); init(); } /** * Standard constructor. See JComboBox API for details */ public SeparatorComboBox(ComboBoxModel model) { super(model); init(); } /** * Standard constructor. See JComboBox API for details */ public SeparatorComboBox(Object[] items) { super(items); init(); } /** * Standard constructor. See JComboBox API for details */ public SeparatorComboBox(Vector<?> items) { super(items); init(); } private void init() { setRenderer(new SeparatorRenderer()); addKeyListener(this); } /** * Prevent selection of the separator by keyboard or mouse */ @Override public void setSelectedIndex(int index) { Object value = getItemAt(index); // Attempting to select a separator if (value instanceof JSeparator) { // If no keys have been pressed then we must be using the mouse. // Prevent selection of the Separator when using the mouse if (released) { separatorSelected = true; return; } // Skip over the Separator when using the Up/Down keys int current = getSelectedIndex(); index += (index > current) ? 1 : -1; if (index == -1 || index >= dataModel.getSize()) return; } super.setSelectedIndex(index); } /** * Prevent closing of the popup when attempting to select the separator with the mouse. */ @Override public void setPopupVisible(boolean visible) { // Keep the popup open when the separator was clicked on if (separatorSelected) { separatorSelected = false; return; } super.setPopupVisible(visible); } // // Implement the KeyListener interface // public void keyPressed(KeyEvent e) { released = false; } public void keyReleased(KeyEvent e) { released = true; } public void keyTyped(KeyEvent e) {} /** * Class to render the JSeparator compenent */ class SeparatorRenderer implements ListCellRenderer { private ListCellRenderer renderer; public SeparatorRenderer() { renderer = new JComboBox().getRenderer(); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value instanceof JSeparator) { return (JSeparator) value; } else { return renderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } } } }