xdev.ui.XdevListBox Maven / Gradle / Ivy
package xdev.ui;
/*-
* #%L
* XDEV Application Framework
* %%
* Copyright (C) 2003 - 2020 XDEV Software
* %%
* This program 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 3 of the
* License, or (at your option) any later version.
*
* This program 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.Beans;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collection;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon;
import javax.swing.JCheckBox;
import javax.swing.JList;
import javax.swing.JViewport;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import xdev.db.Operator;
import xdev.db.sql.Condition;
import xdev.ui.ItemList.Entry;
import xdev.ui.listbox.ListBoxSupport;
import xdev.ui.paging.ListBoxPageControl;
import xdev.ui.paging.Pageable;
import xdev.util.IntList;
import xdev.util.ObjectUtils;
import xdev.util.StringUtils;
import xdev.util.XdevList;
import xdev.vt.VirtualTable;
import xdev.vt.VirtualTable.VirtualTableRow;
import xdev.vt.VirtualTableColumn;
/**
* The standard listbox in XDEV. Based on {@link JList}.
*
* @see JList
*
* @author XDEV Software
*
* @since 2.0
*/
@BeanSettings(useXdevCustomizer = true)
public class XdevListBox extends JList implements ExtendedList,
XdevFocusCycleComponent, PopupRowSelectionHandler, Pageable
{
public final static String CHECKBOX_LIST_PROPERTY = "checkBoxList";
public final static String EVEN_BACKGROUND_PROPERTY = "evenBackground";
public final static String ODD_BACKGROUND_PROPERTY = "oddBackground";
private boolean checkBoxList = false;
private Color evenBackground = null;
private Color oddBackground = null;
/**
* tabIndex is used to store the index for {@link XdevFocusCycleComponent}
* functionality.
*/
private int tabIndex = -1;
// @since 4.0
private boolean pagingEnabled = false;
private ListBoxPageControl pageControl = null;
private final ListBoxSupport support = new ListBoxSupport(
this);
/**
* Constructs a {@link XdevListBox} that is initialized with a default
* {@link ListCellRenderer}.
*
*
* @see #setCheckBoxList(boolean)
* @see #setItemList(ItemList)
*/
public XdevListBox()
{
this(false);
}
/**
* Constructs a {@link XdevListBox} that is initialized with a default
* {@link ListCellRenderer}.
*
*
* @param checkable
* if true
the {@link XdevListBox} items are
* initialized with a checkbox style
*
* @see #setItemList(ItemList)
* @see #setCheckBoxList(boolean)
*/
public XdevListBox(final boolean checkable)
{
this(new ItemList(),checkable);
}
/**
* Constructs a {@link XdevListBox} that is initialized with the
* il
and a default {@link ListCellRenderer}.
*
*
* @param il
* represents the contents or "value" of this {@link XdevListBox}
*
* @see #setItemList(ItemList)
* @see #setCheckBoxList(boolean)
*/
public XdevListBox(final ItemList il)
{
this(il,false);
}
/**
* Constructs a {@link XdevListBox} that is initialized with the
* model
and a default {@link ListCellRenderer}.
*
*
* @param model
* the {@link ListModel} for this {@link XdevListBox}
*
* @see #setModel(ListModel)
* @see #setCheckBoxList(boolean)
*/
public XdevListBox(final ListModel model)
{
this(model,false);
}
/**
* Constructs a {@link XdevListBox} that is initialized with the
* il
and a default {@link ListCellRenderer}.
*
*
* @param il
* represents the contents or "value" of this {@link XdevListBox}
*
* @param checkable
* if true
the {@link XdevListBox} items are
* initialized with a checkbox style
*
* @see #setCheckBoxList(boolean)
* @see #setItemList(ItemList)
*/
public XdevListBox(final ItemList il, final boolean checkable)
{
super();
setSelectionModel(createListSelectionModel());
setItemList(il);
setCheckBoxList0(checkable,true);
}
/**
* Constructs a {@link XdevListBox} that is initialized with the
* model
and a default {@link ListCellRenderer}.
*
*
* @param model
* the {@link ListModel} for this {@link XdevListBox}
*
* @param checkable
* if true
the {@link XdevListBox} items are
* initialized with a checkbox style
*
* @see #setCheckBoxList(boolean)
* @see #setModel(ListModel)
*/
public XdevListBox(final ListModel model, final boolean checkable)
{
super();
setSelectionModel(createListSelectionModel());
setModel(model);
setCheckBoxList0(checkable,true);
}
protected boolean isElementSelectable(final Object item)
{
if(item instanceof Entry)
{
return ((Entry)item).isEnabled();
}
return true;
}
/**
* Sets if this list should use checkboxes to render the list entries.
*
* @param checkBoxList
* true
if this list should use checkboxes
*/
public void setCheckBoxList(final boolean checkBoxList)
{
setCheckBoxList0(checkBoxList,false);
}
private void setCheckBoxList0(final boolean checkBoxList, final boolean force)
{
if(this.checkBoxList != checkBoxList || force)
{
final boolean oldValue = this.checkBoxList;
this.checkBoxList = checkBoxList;
UIUtils.removeMouseListener(this,CheckableHandler.class);
UIUtils.removeMouseMotionListener(this,CheckableHandler.class);
if(checkBoxList)
{
setCellRenderer(createCheckBoxListCellRenderer());
final CheckableHandler checkableHandler = new CheckableHandler();
UIUtils.insertMouseListener(this,checkableHandler,0);
UIUtils.insertMouseMotionListener(this,checkableHandler,0);
}
else
{
setCellRenderer(createDefaultListCellRenderer());
}
firePropertyChange(CHECKBOX_LIST_PROPERTY,oldValue,checkBoxList);
}
}
protected ListSelectionModel createListSelectionModel()
{
return new XdevListSelectionModel();
}
protected ListCellRenderer createDefaultListCellRenderer()
{
return new XdevListCellRenderer();
}
protected ListCellRenderer createCheckBoxListCellRenderer()
{
return new XdevCheckBoxListCellRenderer();
}
/**
* Returns true
if the items
of this
* {@link XdevListBox} were drawn with a checkbox style.
*
* @return true
if the items
of this
* {@link XdevListBox} were drawn with a checkbox style, otherwise
* false
.
*/
public boolean isCheckBoxList()
{
return this.checkBoxList;
}
/**
* {@inheritDoc}
*/
@Override
public ItemList getItemList()
{
return this.support.getItemList();
}
/**
* {@inheritDoc}
*/
@Override
@BeanProperty(category = DefaultBeanCategories.DATA)
public void setItemList(final ItemList itemList)
{
setModel(new ItemListModelWrapper(itemList));
}
/**
*
* Create a new {@link ItemList} based on the provided model
.
* The data are the model's values and the item's are the model's values as
* {@link String}.
*
* @param model
* The {@link ListModel}
*
* @return the new {@link ItemList}
*/
public ItemList modelToItemList(final ListModel model)
{
return new ItemList(model);
}
/**
* {@inheritDoc}
*/
@Override
public void setModel(final VirtualTable vt, final String itemCol, final String dataCol)
{
setModel(vt,itemCol,dataCol,false);
}
/**
* {@inheritDoc}
*/
@Override
public void setModel(final VirtualTable vt, final String itemCol, final String dataCol,
final boolean queryData)
{
setModel(vt,itemCol,dataCol,queryData,false);
}
/**
* {@inheritDoc}
*/
@Override
public void setModel(final VirtualTable vt, final String itemCol, final String dataCol,
final boolean queryData, final boolean selectiveQuery)
{
if(getItemList() == null)
{
setItemList(new ItemList());
}
getItemList().setModel(vt,itemCol,dataCol,queryData,selectiveQuery);
clearSelection();
}
/**
* {@inheritDoc}
*
* @since 4.0
*/
@Override
public void setPagingEnabled(final boolean pagingEnabled)
{
this.pagingEnabled = pagingEnabled;
if(!Beans.isDesignTime())
{
if(pagingEnabled)
{
getItemList().setPageControl(getPageControl());
}
else
{
getItemList().setPageControl(null);
}
refresh();
}
}
/**
* {@inheritDoc}
*
* @since 4.0
*/
@Override
public boolean isPagingEnabled()
{
return this.pagingEnabled;
}
/**
* {@inheritDoc}
*
* @since 4.0
*/
@Override
public ListBoxPageControl getPageControl()
{
if(this.pageControl == null)
{
this.pageControl = new ListBoxPageControl(this);
}
return this.pageControl;
}
/**
* {@inheritDoc}
*/
@Override
public void refresh()
{
this.support.refresh();
}
/**
* {@inheritDoc}
*/
@Override
public void updateModel(final Condition condition, final Object... params)
{
this.support.updateModel(condition,params);
}
/**
* {@inheritDoc}
*/
@Override
public void clearModel()
{
this.support.clearModel();
}
/**
* Sets the background {@link Color} of even rows.
*
* @param evenBackground
* The background of even rows as type {@link Color}.
*/
@BeanProperty(category = DefaultBeanCategories.DESIGN)
public void setEvenBackground(final Color evenBackground)
{
if(!ObjectUtils.equals(this.evenBackground,evenBackground))
{
final Object oldValue = this.evenBackground;
this.evenBackground = evenBackground;
firePropertyChange(EVEN_BACKGROUND_PROPERTY,oldValue,evenBackground);
}
}
/**
* Returns the background {@link Color} of even rows.
*
* @return The background of even rows as type {@link Color}.
*/
public Color getEvenBackground()
{
return this.evenBackground;
}
/**
* Sets the background {@link Color} of odd rows.
*
* @param oddBackground
* The background of odd rows as type {@link Color}.
*/
@BeanProperty(category = DefaultBeanCategories.DESIGN)
public void setOddBackground(final Color oddBackground)
{
if(!ObjectUtils.equals(this.oddBackground,oddBackground))
{
final Object oldValue = this.oddBackground;
this.oddBackground = oddBackground;
firePropertyChange(ODD_BACKGROUND_PROPERTY,oldValue,oddBackground);
}
}
/**
* Returns the background {@link Color} of odd rows.
*
* @return The background of odd rows as type {@link Color}.
*/
public Color getOddBackground()
{
return this.oddBackground;
}
/**
* Select all items in the {@link XdevListBox}.
*
* @see ListSelectionModel#clearSelection()
* @see ListSelectionModel#setSelectionInterval(int, int)
*/
public void selectAll()
{
final int size = getModel().getSize();
if(size > 0)
{
getSelectionModel().clearSelection();
getSelectionModel().setSelectionInterval(0,size);
}
}
/**
* Verify if a item is selected.
*
* @return true
if a item is selected, otherwise
* false
.
*/
public boolean isSomethingSelected()
{
return getSelectedIndex() >= 0;
}
/**
* Changes the selection to be the set of indices specified by the given
* {@link XdevList}. Indices greater than or equal to the model size are
* ignored. This is a convenience method that clears the selection and then
* uses {@code addSelectionInterval} on the selection model to add the
* indices. Refer to the documentation of the selection model class being
* used for details on how values less than {@code 0} are handled.
*
* @param indices
* an {@link XdevList} of the indices of the cells to select,
* {@code non-null}
*
* @see #setSelectedIndices(int[])
*/
public void setSelectedIndices(final Collection indices)
{
final IntList intList = new IntList();
for(final Integer index : indices)
{
if(index != null)
{
intList.add(index);
}
}
setSelectedIndices(intList.toArray());
}
/**
* Returns a {@link XdevList} of all of the selected indices, in increasing
* order.
*
* @return all of the selected indices, in increasing order, or an empty
* {@link XdevList} if nothing is selected
*
*/
public XdevList getSelectedIndicesAsList()
{
final XdevList list = new XdevList();
final int[] si = getSelectedIndices();
for(int i = 0; i < si.length; i++)
{
list.add(si[i]);
}
return list;
}
/**
* Returns the modelindex of the selected item.
*
* For example the index of the selected item in it is {@link VirtualTable}.
*
*
* @return an integer specifying the currently selected list item, where 0
* specifies the first item in the list; or -1 if no item is
* selected or if the currently selected item is not in the list
*/
public int getSelectedModelIndex()
{
return this.support.getSelectedModelIndex(super.getSelectedIndex());
}
/**
* Returns the modelindices of the selected items.
*
* For example the indices of the selected items in their model
* {@link VirtualTable}.
*
*
* @return an integer specifying the currently selected list item, where 0
* specifies the first item in the list; or -1 if no item is
* selected or if the currently selected item is not in the list
*/
public int[] getSelectedModelIndices()
{
return this.support.getSelectedModelIndices(super.getSelectedIndices());
}
/**
* Selects the items at their modelindices position indices
.
*
* For example the given indices of the items in their model
* {@link VirtualTable} .
*
*
* @param indices
* an integer specifying the list item to select, where 0
* specifies the first item in the list and -1 indicates no
* selection.
*/
public void setSelectedModelIndices(final int[] indices)
{
this.support.setSelectedModelIndices(indices);
}
/**
* Selects the item at modelindex anIndex
.
*
* For example the given index of an item in it is model {@link VirtualTable}
* .
*
*
* @param index
* an integer specifying the list item to select, where 0
* specifies the first item in the list and -1 indicates no
* selection
*/
public void setSelectedModelIndex(final int index)
{
this.support.setSelectedModelIndex(index);
}
/**
* Selects all entries with an item in the list items
.
*
* @param items
* the items to select
*
* @since 3.1
*/
public void setSelectedItems(final Collection> items)
{
this.support.setSelectedItems(items);
}
/**
* Returns the item for the selected value from {@link ItemList}.
*
* @return the item for the selected value from {@link ItemList}
*/
public Object getSelectedItem()
{
return getSelectedValue();
}
/**
* Returns all items of the selected list entries as a list.
*
* If nothing is selected an empty list is returned.
*
*
* @return all selected items or an empty list if nothing is selected.
*
* @since 3.1
*/
public XdevList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy