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 (c) 1995-2012, The University of Sheffield. See the file
* COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
*
* This file is part of GATE (see http://gate.ac.uk/), and is free
* software, licenced under the GNU Library General Public License,
* Version 2, June 1991 (in the distribution as file licence.html,
* and also available at http://gate.ac.uk/gate/licence.html).
*
* Valentin Tablan, 13 Sep 2007
*
* $Id: JChoice.java 17874 2014-04-18 11:19:47Z markagreenwood $
*/
package gate.swing;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.ItemSelectable;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.EventListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.event.ListDataListener;
/**
* A GUI component intended to allow quick selection from a set of
* options. When the number of choices is small (i.e less or equal to
* {@link #maximumFastChoices}) then the options are represented as a
* set of buttons in a flow layout. If more options are available, a
* simple {@link JComboBox} is used instead.
*/
@SuppressWarnings("serial")
public class JChoice extends JPanel implements ItemSelectable {
@Override
public Object[] getSelectedObjects() {
return new Object[]{getSelectedItem()};
}
/**
* The default value for the {@link #maximumWidth} parameter.
*/
public static final int DEFAULT_MAX_WIDTH = 500;
/**
* The default value for the {@link #maximumFastChoices} parameter.
*/
public static final int DEFAULT_MAX_FAST_CHOICES = 10;
/**
* The maximum number of options for which the flow of buttons is used
* instead of a combobox. By default this value is
* {@link #DEFAULT_MAX_FAST_CHOICES}
*/
private int maximumFastChoices;
/**
* Margin used for choice buttons.
*/
private Insets defaultButtonMargin;
/**
* The maximum width allowed for this component. This value is only
* used when the component appears as a flow of buttons. By default
* this value is {@link #DEFAULT_MAX_WIDTH}. This is used to force the flow
* layout do a multi-line layout, as by default it prefers to lay all
* components in a single very wide line.
*/
private int maximumWidth;
/**
* The layout used by this container.
*/
private FlowLayout layout;
/**
* The combobox used for a large number of choices.
*/
private JComboBox combo;
/**
* Internal item listener for both the combo and the buttons, used to keep
* the two in sync.
*/
private ItemListener sharedItemListener;
/**
* The data model used for choices and selection.
*/
private ComboBoxModel model;
/**
* Keeps a mapping between the button and the corresponding option from the
* model.
*/
private Map buttonToValueMap;
/**
* Creates a FastChoice with a default empty data model.
*/
public JChoice() {
this(new DefaultComboBoxModel());
}
/**
* A map from wrapped action listeners to listener
*/
private Map listenersMap;
/**
* Creates a FastChoice with the given data model.
*/
public JChoice(ComboBoxModel model) {
layout = new FlowLayout();
layout.setHgap(0);
layout.setVgap(0);
layout.setAlignment(FlowLayout.LEFT);
setLayout(layout);
this.model = model;
//by default nothing is selected
setSelectedItem(null);
initLocalData();
buildGui();
}
/**
* Creates a FastChoice with a default data model populated from the provided
* array of objects.
*/
public JChoice(E[] items) {
this(new DefaultComboBoxModel(items));
}
/**
* Initialises some local values.
*/
private void initLocalData(){
maximumFastChoices = DEFAULT_MAX_FAST_CHOICES;
maximumWidth = DEFAULT_MAX_WIDTH;
listenersMap = new HashMap();
combo = new JComboBox(model);
buttonToValueMap = new HashMap();
sharedItemListener = new ItemListener(){
/**
* Flag used to disable event handling while generating events. Used as an
* exit mechanism from event handling loops.
*/
private boolean disabled = false;
@Override
public void itemStateChanged(ItemEvent e) {
if(disabled) return;
if(e.getSource() == combo){
//event from the combo
//disable event handling, to avoid unwanted cycles
disabled = true;
if(e.getStateChange() == ItemEvent.SELECTED){
//update the state of all buttons
for(AbstractButton aBtn : buttonToValueMap.keySet()){
Object aValue = buttonToValueMap.get(aBtn);
if(aValue.equals(e.getItem())){
//this is the selected button
if(!aBtn.isSelected()){
aBtn.setSelected(true);
aBtn.requestFocusInWindow();
}
}else{
//this is a button that should not be selected
if(aBtn.isSelected()) aBtn.setSelected(false);
}
}
}else if(e.getStateChange() == ItemEvent.DESELECTED){
//deselections due to other value being selected are handled
//above.
//here we only need to handle the case when the selection was
//removed, but not replaced (i.e. setSelectedItem(null)
for(AbstractButton aBtn : buttonToValueMap.keySet()){
Object aValue = buttonToValueMap.get(aBtn);
if(aValue.equals(e.getItem())){
//this is the de-selected button
if(aBtn.isSelected()) aBtn.setSelected(false);
}
}
}
//re-enable event handling
disabled = false;
}else if(e.getSource() instanceof AbstractButton){
//event from the buttons
if(buttonToValueMap.containsKey(e.getSource())){
Object value = buttonToValueMap.get(e.getSource());
if(e.getStateChange() == ItemEvent.SELECTED){
model.setSelectedItem(value);
}else if(e.getStateChange() == ItemEvent.DESELECTED){
model.setSelectedItem(null);
}
}
}
}
};
combo.addItemListener(sharedItemListener);
}
public static void main(String[] args){
final JChoice fChoice = new JChoice(new String[]{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"});
fChoice.setMaximumFastChoices(20);
fChoice.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Action (" + e.getActionCommand() + ") :" + fChoice.getSelectedItem() + " selected!");
}
});
fChoice.addItemListener(new ItemListener(){
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println("Item " + e.getItem().toString() +
(e.getStateChange() == ItemEvent.SELECTED ? " selected!" :
" deselected!"));
}
});
JFrame aFrame = new JFrame("Fast Chioce Test Frame");
aFrame.getContentPane().add(fChoice);
Box topBox = Box.createHorizontalBox();
JButton aButn = new JButton("Clear");
aButn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Clearing");
fChoice.setSelectedItem(null);
}
});
topBox.add(Box.createHorizontalStrut(10));
topBox.add(aButn);
topBox.add(Box.createHorizontalStrut(10));
topBox.add(new JToggleButton("GAGA"));
aFrame.add(topBox, BorderLayout.NORTH);
aFrame.pack();
aFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
aFrame.setVisible(true);
}
/**
* @param l
* @see javax.swing.JComboBox#removeActionListener(java.awt.event.ActionListener)
*/
public void removeActionListener(ActionListener l) {
ListenerWrapper wrapper = listenersMap.remove(l);
combo.removeActionListener(wrapper);
}
/**
* @param listener
* @see javax.swing.JComboBox#removeItemListener(java.awt.event.ItemListener)
*/
@Override
public void removeItemListener(ItemListener listener) {
ListenerWrapper wrapper = listenersMap.remove(listener);
combo.removeActionListener(wrapper);
}
/**
* @param l
* @see javax.swing.JComboBox#addActionListener(java.awt.event.ActionListener)
*/
public void addActionListener(ActionListener l) {
combo.addActionListener(new ListenerWrapper(l));
}
/**
* @param listener
* @see javax.swing.JComboBox#addItemListener(java.awt.event.ItemListener)
*/
@Override
public void addItemListener(ItemListener listener) {
combo.addItemListener(new ListenerWrapper(listener));
}
/**
* (Re)constructs the UI. This can be called many times, whenever a
* significant value (such as {@link #maximumFastChoices}, or the model)
* has changed.
*/
private void buildGui(){
removeAll();
if(model != null && model.getSize() > 0){
if(model.getSize() > maximumFastChoices){
//use combobox
add(combo);
}else{
//use buttons
//first clear the old buttons, if any exist
if(buttonToValueMap.size() > 0){
for(AbstractButton aBtn : buttonToValueMap.keySet()){
aBtn.removeItemListener(sharedItemListener);
}
}
//now create the new buttons
buttonToValueMap.clear();
for(int i = 0; i < model.getSize(); i++){
Object aValue = model.getElementAt(i);
JToggleButton aButton = new JToggleButton(aValue.toString());
if(defaultButtonMargin != null) aButton.setMargin(defaultButtonMargin);
aButton.addItemListener(sharedItemListener);
buttonToValueMap.put(aButton, aValue);
add(aButton);
}
}
}
revalidate();
}
/**
* @param l
* @see javax.swing.ListModel#addListDataListener(javax.swing.event.ListDataListener)
*/
public void addListDataListener(ListDataListener l) {
model.addListDataListener(l);
}
/**
* @see javax.swing.ListModel#getElementAt(int)
*/
public Object getElementAt(int index) {
return model.getElementAt(index);
}
/**
* @see javax.swing.ComboBoxModel#getSelectedItem()
*/
public Object getSelectedItem() {
return model.getSelectedItem();
}
/**
* @see javax.swing.ListModel#getSize()
*/
public int getItemCount() {
return model.getSize();
}
/**
* @param l
* @see javax.swing.ListModel#removeListDataListener(javax.swing.event.ListDataListener)
*/
public void removeListDataListener(ListDataListener l) {
model.removeListDataListener(l);
}
/**
* @param anItem
* @see javax.swing.ComboBoxModel#setSelectedItem(java.lang.Object)
*/
public void setSelectedItem(Object anItem) {
model.setSelectedItem(anItem);
}
/*
* (non-Javadoc)
*
* @see javax.swing.JComponent#getPreferredSize()
*/
@Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
if(getItemCount() <= maximumFastChoices && size.width > maximumWidth) {
setSize(maximumWidth, Integer.MAX_VALUE);
doLayout();
int compCnt = getComponentCount();
if(compCnt > 0) {
Component lastComp = getComponent(compCnt - 1);
Point compLoc = lastComp.getLocation();
Dimension compSize = lastComp.getSize();
size.width = maximumWidth;
size.height = compLoc.y + compSize.height + getInsets().bottom;
}
}
return size;
}
/**
* @return the maximumFastChoices
*/
public int getMaximumFastChoices() {
return maximumFastChoices;
}
/**
* @param maximumFastChoices the maximumFastChoices to set
*/
public void setMaximumFastChoices(int maximumFastChoices) {
this.maximumFastChoices = maximumFastChoices;
buildGui();
}
/**
* @return the model
*/
public ComboBoxModel getModel() {
return model;
}
/**
* @param model the model to set
*/
public void setModel(ComboBoxModel model) {
this.model = model;
combo.setModel(model);
buildGui();
}
/**
* @return the maximumWidth
*/
public int getMaximumWidth() {
return maximumWidth;
}
/**
* @param maximumWidth the maximumWidth to set
*/
public void setMaximumWidth(int maximumWidth) {
this.maximumWidth = maximumWidth;
}
/**
* An action listener that changes the source of events to be this object.
*/
private class ListenerWrapper implements ActionListener, ItemListener{
public ListenerWrapper(EventListener originalListener) {
this.originalListener = originalListener;
listenersMap.put(originalListener, this);
}
@Override
public void itemStateChanged(ItemEvent e) {
//generate a new event with this as source
((ItemListener)originalListener).itemStateChanged(
new ItemEvent(JChoice.this, e.getID(), e.getItem(),
e.getStateChange()));
}
@Override
public void actionPerformed(ActionEvent e) {
//generate a new event
((ActionListener)originalListener).actionPerformed(new ActionEvent(
JChoice.this, e.getID(), e.getActionCommand(), e.getWhen(),
e.getModifiers()));
}
private EventListener originalListener;
}
/**
* @return the defaultButtonMargin
*/
public Insets getDefaultButtonMargin() {
return defaultButtonMargin;
}
/**
* @param defaultButtonMargin the defaultButtonMargin to set
*/
public void setDefaultButtonMargin(Insets defaultButtonMargin) {
this.defaultButtonMargin = defaultButtonMargin;
buildGui();
}
}