Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2010 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jdesktop.swingx;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.beans.BeanProperty;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Vector;
import javax.accessibility.Accessible;
import javax.swing.ComboBoxEditor;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.ComboPopup;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.CompoundHighlighter;
import org.jdesktop.swingx.decorator.Highlighter;
import org.jdesktop.swingx.plaf.LookAndFeelAddons;
import org.jdesktop.swingx.plaf.UIDependent;
import org.jdesktop.swingx.plaf.XComboBoxAddon;
import org.jdesktop.swingx.plaf.XComboBoxUI;
import org.jdesktop.swingx.renderer.DefaultListRenderer;
import org.jdesktop.swingx.renderer.JRendererPanel;
import org.jdesktop.swingx.renderer.StringValue;
import org.jdesktop.swingx.rollover.RolloverRenderer;
import org.jdesktop.swingx.sort.ListSortController;
import org.jdesktop.swingx.sort.SortController;
import org.jdesktop.swingx.sort.StringValueRegistry;
import org.jdesktop.swingx.util.Contract;
/**
* An enhanced {@code JComboBox} that provides the following additional functionality:
*
* Auto-starts edits correctly for AutoCompletion when inside a {@code JTable}.
* A normal {@code JComboBox} fails to recognize the first key stroke when it has been
* {@link org.jdesktop.swingx.autocomplete.AutoCompleteDecorator#decorate(JComboBox) decorated}.
*
* Adds highlighting support.
* User defined ComboBoxIcon.
* Add sort api: autoCreateRowSorter
*
* @see org.jdesktop.swingx.JXList
*
* @author Karl Schaefer
* @author Jeanette Winzenburg
* @author EUG https://github.com/homebeaver
*/
@SuppressWarnings("serial")
public class JXComboBox extends JComboBox {
static {
LookAndFeelAddons.contribute(new XComboBoxAddon());
}
/**
* UI Class ID
* @see #getUIClassID
* @see javax.swing.JComponent#readObject
*/
public static final String uiClassID = "XComboBoxUI";
/**
* Returns a string that specifies the name of the LaF class that renders this component.
*
* @return the string {@code uiClassID}
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
@BeanProperty(bound = false)
public String getUIClassID() {
return uiClassID;
}
/**
* A decorator for the original ListCellRenderer.
* Needed to hook highlighters after messaging the delegate.
*/
public class DelegatingRenderer implements ListCellRenderer, RolloverRenderer, UIDependent {
/** the delegate. */
private ListCellRenderer super E> delegateRenderer;
private JRendererPanel wrapper;
/**
* Instantiates a DelegatingRenderer with combo box's default renderer as delegate.
*/
public DelegatingRenderer() {
this(null);
}
/**
* Instantiates a DelegatingRenderer with the given delegate. If the
* delegate is {@code null}, the default is created via the combo box's factory method.
*
* @param delegate the delegate to use, if {@code null} the combo box's default is
* created and used.
*/
public DelegatingRenderer(ListCellRenderer delegate) {
wrapper = new JRendererPanel(new BorderLayout());
setDelegateRenderer(delegate);
}
/**
* Sets the delegate. If the delegate is {@code null}, the default is created via the combo
* box's factory method.
*
* @param delegate
* the delegate to use, if null the list's default is created and used.
*/
public void setDelegateRenderer(ListCellRenderer super E> delegate) {
if (delegate == null) {
delegate = createDefaultCellRenderer();
}
delegateRenderer = delegate;
}
/**
* Returns the delegate.
*
* @return the delegate renderer used by this renderer, guaranteed to not-null.
*/
public ListCellRenderer super E> getDelegateRenderer() {
return delegateRenderer;
}
/**
* {@inheritDoc}
*/
@Override
public void updateUI() {
wrapper.updateUI();
if (delegateRenderer instanceof UIDependent uiDelegateRenderer) {
uiDelegateRenderer.updateUI();
} else if (delegateRenderer instanceof Component comp) {
SwingUtilities.updateComponentTreeUI(comp);
} else if (delegateRenderer != null) {
// ListCellRenderer super E> delegateRenderer, dh superclass von E
try {
// cast info
// JList extends Object> getPopupListFor
// interface : getListCellRendererComponent( JList extends E> list, E value, ...
JList extends Object> lo = getPopupListFor(JXComboBox.this);
@SuppressWarnings("unchecked")
JList extends E> list = (JList extends E>)lo;
Component comp = delegateRenderer.getListCellRendererComponent(list, null, -1, false, false);
SwingUtilities.updateComponentTreeUI(comp);
} catch (Exception e) {
// nothing to do - renderer barked on off-range row
}
}
}
// --------- implement ListCellRenderer
/**
* {@inheritDoc}
*
* Overridden to apply the highlighters, if any, after calling the delegate.
* The decorators are not applied if the row is invalid.
*/
@Override
public Component getListCellRendererComponent(JList extends E> list, E value, int index,
boolean isSelected, boolean cellHasFocus) {
Component comp = null;
if (index == -1) {
comp = delegateRenderer.getListCellRendererComponent(list, value, getSelectedIndex(), isSelected, cellHasFocus);
if (isUsingHighlightersForCurrentValue() && compoundHighlighter != null && getSelectedIndex() != -1) {
comp = compoundHighlighter.highlight(comp, getComponentAdapter(getSelectedIndex()));
// this is done to "trick" BasicComboBoxUI.paintCurrentValue which resets all of
// the painted information after asking the list to render the value. the panel
// wrappers receives all of the post-rendering configuration, which is dutifully
// ignored by the real rendering component
wrapper.add(comp);
comp = wrapper;
}
} else {
comp = delegateRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if ((compoundHighlighter != null) && (index >= 0) && (index < getItemCount())) {
comp = compoundHighlighter.highlight(comp, getComponentAdapter(index));
}
}
return comp;
}
// implement RolloverRenderer
/**
* {@inheritDoc}
*
*/
@Override
public boolean isEnabled() {
return (delegateRenderer instanceof RolloverRenderer) &&
((RolloverRenderer) delegateRenderer).isEnabled();
}
/**
* {@inheritDoc}
*/
@Override
public void doClick() {
if (isEnabled()) {
((RolloverRenderer) delegateRenderer).doClick();
}
}
}
protected static class ComboBoxAdapter extends ComponentAdapter {
private final JXComboBox> comboBox;
/**
* Constructs a ListAdapter for the specified target JXList.
*
* @param component the target list.
*/
public ComboBoxAdapter(JXComboBox> component) {
super(component);
comboBox = component;
}
/**
* Typesafe accessor for the target component.
*
* @return the target component as a {@link org.jdesktop.swingx.JXComboBox}
*/
public JXComboBox> getComboBox() {
return comboBox;
}
/**
* A safe way to access the combo box's popup visibility.
*
* @return {@code true} if the popup is visible; {@code false} otherwise
*/
protected boolean isPopupVisible() {
if (comboBox.updatingUI) {
return false;
}
return comboBox.isPopupVisible();
}
/**
* {@inheritDoc}
*/
@Override
public boolean hasFocus() {
if (isPopupVisible()) {
JList extends Object> list = getPopupListFor(comboBox);
return list != null && list.isFocusOwner() && (row == list.getLeadSelectionIndex());
}
return comboBox.isFocusOwner();
}
/**
* {@inheritDoc}
*/
@Override
public int getRowCount() {
return comboBox.getModel().getSize();
}
/**
* {@inheritDoc}
*/
@Override
public Object getValueAt(int row, int column) {
return comboBox.getModel().getElementAt(row);
}
/**
* {@inheritDoc}
* This is implemented to query the table's StringValueRegistry for an appropriate
* StringValue and use that for getting the string representation.
*/
@Override
public String getStringAt(int row, int column) {
StringValue sv = comboBox.getStringValueRegistry().getStringValue(row, column);
return sv.getString(getValueAt(row, column));
}
/**
* {@inheritDoc}
*/
@Override
public Rectangle getCellBounds() {
JList extends Object> list = getPopupListFor(comboBox);
if (list == null) {
assert false;
return new Rectangle(comboBox.getSize());
}
return list.getCellBounds(row, row);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isCellEditable(int row, int column) {
return row == -1 && comboBox.isEditable();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEditable() {
return isCellEditable(row, column);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isSelected() {
if (isPopupVisible()) {
JList extends Object> list = getPopupListFor(comboBox);
return list != null && row == list.getLeadSelectionIndex();
}
return comboBox.isFocusOwner();
}
}
class StringValueKeySelectionManager implements KeySelectionManager, Serializable, UIDependent {
private long timeFactor;
private long lastTime = 0L;
private String prefix = "";
private String typedString = "";
public StringValueKeySelectionManager() {
updateUI();
}
@Override
public int selectionForKey(char aKey, ComboBoxModel> aModel) {
if (lastTime == 0L) {
prefix = "";
typedString = "";
}
int startIndex = getSelectedIndex();
if (EventQueue.getMostRecentEventTime() - lastTime < timeFactor) {
typedString += aKey;
if ((prefix.length() == 1) && (aKey == prefix.charAt(0))) {
// Subsequent same key presses move the keyboard focus to the next
// object that starts with the same letter.
startIndex++;
} else {
prefix = typedString;
}
} else {
startIndex++;
typedString = "" + aKey;
prefix = typedString;
}
lastTime = EventQueue.getMostRecentEventTime();
if (startIndex < 0 || startIndex >= aModel.getSize()) {
startIndex = 0;
}
for (int i = startIndex, c = aModel.getSize(); i < c; i++) {
String v = getStringAt(i).toLowerCase();
if (v.length() > 0 && v.charAt(0) == aKey) {
return i;
}
}
for (int i = startIndex, c = aModel.getSize(); i < c; i++) {
String v = getStringAt(i).toLowerCase();
if (v.length() > 0 && v.charAt(0) == aKey) {
return i;
}
}
for (int i = 0; i < startIndex; i++) {
String v = getStringAt(i).toLowerCase();
if (v.length() > 0 && v.charAt(0) == aKey) {
return i;
}
}
return -1;
}
@Override
public void updateUI() {
Long l = (Long) UIManager.get("ComboBox.timeFactor");
timeFactor = l == null ? 1000L : l.longValue();
}
}
/**
* Returns the PopupList of a comboBox.
* @param comboBox JComboBox
* @return JList of Objects
*/
protected static JList extends Object> getPopupListFor(JComboBox extends Object> comboBox) {
int count = comboBox.getUI().getAccessibleChildrenCount(comboBox);
for (int i = 0; i < count; i++) {
Accessible a = comboBox.getUI().getAccessibleChild(comboBox, i);
// interface ComboPopup with method public JList