com.publicobject.amazonbrowser.swing.TreeCriteriaEditor Maven / Gradle / Ivy
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package com.publicobject.amazonbrowser.swing;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.FunctionList;
import ca.odell.glazedlists.event.ListEvent;
import ca.odell.glazedlists.event.ListEventListener;
import ca.odell.glazedlists.matchers.Matchers;
import com.publicobject.amazonbrowser.TreeCriterion;
import com.publicobject.misc.swing.JListPanel;
import com.publicobject.misc.swing.RoundedBorder;
import com.publicobject.misc.swing.Gripper;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A TreeCriteriaEditor is a UI Component capable of editing a List of
* TreeCriteria objects to specify:
*
*
* - which {@link TreeCriterion} objects are active, and thus contribute to the treetable hierarchy
*
- the order of the active TreeCriterion objects, and thus the order of the treetable hierarchies
*
*
* PropertyChangeEvents are fired when the list of active {@link TreeCriterion}
* objects as returned by {@link #getActiveCriteria()} changes in any way.
*
* @author James Lemieux
*/
public class TreeCriteriaEditor extends JListPanel {
/** Only the active {@link TreeCriterion} objects. */
private final EventList activeCriteria;
/** A ListEventListener that watches the {@link #activeCriteria} List for changes and broadcasts PropertyChangeEvents describing the change. */
private final ListEventListener activeCriteriaListener = new ActiveCriteriaListener();
/**
* Construct a TreeCriteriaEditor that allows users a chance to reorder the
* {@link TreeCriterion} objects in the given source
as well
* as activating/deactivating them.
*
* @param source the List of all possible TreeCriterion objects available
*/
public TreeCriteriaEditor(EventList source) {
super(new FunctionList(source, new ForwardFunction(), new ReverseFunction()));
// build a filtered view of allCriteria that only contains active TreeCriterion objects
this.activeCriteria = new FilterList(source, Matchers.beanPropertyMatcher(TreeCriterion.class, "active", Boolean.TRUE));
this.activeCriteria.addListEventListener(activeCriteriaListener);
}
/**
* Returns an unmodifiable snapshot List of active
* {@link TreeCriterion} objects.
*/
public List getActiveCriteria() {
return Collections.unmodifiableList(new ArrayList(activeCriteria));
}
/**
* This ListEventListener translates changes to the List of active criteria
* into PropertyChangeEvents for the activeCriteria property of this
* TreeCriteriaEditor.
*/
private class ActiveCriteriaListener implements ListEventListener {
@Override
public void listChanged(ListEvent listChanges) {
firePropertyChange("activeCriteria", null, getActiveCriteria());
}
}
/**
* A function capable of mapping TreeCriterion objects to the
* TreeCriterionEditorPanel that edits them.
*/
private static class ForwardFunction implements FunctionList.Function {
@Override
public TreeCriterionEditorPanel evaluate(TreeCriterion tc) {
return new TreeCriterionEditorPanel(tc);
}
}
/**
* A function capable of mapping TreeCriterionEditorPanel objects back to the
* TreeCriterion that edits them.
*/
private static class ReverseFunction implements FunctionList.Function {
@Override
public TreeCriterion evaluate(TreeCriterionEditorPanel c) {
return c.getTreeCriterion();
}
}
/**
* A special panel that combines a JButton which indicates the active state
* of a TreeCriterion with a JLabel that displays the name of the
* TreeCriterion.
*/
public static class TreeCriterionEditorPanel extends JPanel implements PropertyChangeListener {
private final JButton activeButton = new JButton();
private final JLabel nameLabel = new JLabel();
private final JLabel gripLabel = new JLabel();
private final TreeCriterion treeCriterion;
public TreeCriterionEditorPanel(TreeCriterion tc) {
super(new BorderLayout());
this.treeCriterion = tc;
this.treeCriterion.addPropertyChangeListener(this);
setBackground(AmazonBrowser.AMAZON_SEARCH_DARK_BLUE);
setBorder(new RoundedBorder(AmazonBrowser.AMAZON_SEARCH_LIGHT_BLUE, AmazonBrowser.AMAZON_SEARCH_LIGHT_BLUE, AmazonBrowser.AMAZON_SEARCH_DARK_BLUE, 6, 1));
activeButton.addActionListener(new ButtonHandler());
activeButton.setBorder(BorderFactory.createEmptyBorder());
activeButton.setContentAreaFilled(false);
activeButton.setFocusable(false);
activeButton.setFont(nameLabel.getFont().deriveFont(8));
nameLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
nameLabel.setForeground(AmazonBrowser.AMAZON_TAB_LIGHT_BEIGE);
nameLabel.setFont(nameLabel.getFont().deriveFont(8));
gripLabel.setIcon(new Gripper(10, 19, AmazonBrowser.AMAZON_TAB_LIGHT_BEIGE, Color.BLACK, AmazonBrowser.AMAZON_SEARCH_DARK_BLUE));
add(activeButton, BorderLayout.WEST);
add(nameLabel, BorderLayout.CENTER);
add(gripLabel, BorderLayout.EAST);
update();
}
public TreeCriterion getTreeCriterion() {
return treeCriterion;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
update();
}
private void update() {
// todo, Jesse: make this a cool image!
activeButton.setText(treeCriterion.isActive() ? "X" : "O");
nameLabel.setText(treeCriterion.getName());
}
private class ButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
treeCriterion.setActive(!treeCriterion.isActive());
}
}
}
}