//
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
/**
* Copyright (c) 2008, Collin Fagan All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer. Redistributions in binary
* form must reproduce the above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or other materials provided
* with the distribution. Neither the name of aberrantcode.blogspot.com nor the
* names of its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* Demo class is an experiment to show some uses for the closure proposal FCM
* (http://www.jroller.com/scolebourne/date/20080224). It only works on a
* special prototype branch of java available from https://kijaro.dev.java.net/.
*
* @author Collin Fagan
* @email my email service is gmail and my user name is collin.fagan
*/
public class FCMModelsDemo {
/**
* @param args
*/
public static void main(String[] args) {
FCMModelsDemo ezMods = new FCMModelsDemo();
}
/**
* builds the demo on the EDT
*/
public FCMModelsDemo(){
SwingUtilities.invokeLater(#startApp());
}
/**
* Date Renderer Component
*/
private SimpleDateFormat sdfDateColumn = new SimpleDateFormat(
"MMMM-dd-yyyy");
private JLabel dateRenderer = new JLabel();
/**
* startup method
*/
private void startApp(){
JFrame demoFrame = new JFrame();
demoFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
demoFrame.setSize(600,400);
demoFrame.setLayout(new BorderLayout());
// the list of all superhero data
List heroes = buildData();
JPanel listExamples = new JPanel();
listExamples.setLayout(new BoxLayout(listExamples, BoxLayout.Y_AXIS));
// First Name List
JList firstNameList = new JList();
FCMFieldListModel listModel = new FCMFieldListModel(heroes, SuperHero#firstName);
firstNameList.setModel(listModel);
listExamples.add(addTitle("First Name", new JScrollPane(firstNameList)));
// Last Name List
JList lastNameList = new JList();
FCMFieldListModel lastListModel = new FCMFieldListModel(heroes, SuperHero#lastName);
lastNameList.setModel(lastListModel);
listExamples.add(addTitle("Last Name", new JScrollPane(lastNameList)));
// Full Name List
JList fullNameList = new JList();
FCMMethodListModel fullListModel = new FCMMethodListModel(heroes, SuperHero#getFullName());
fullNameList.setModel(fullListModel);
demoFrame.add(listExamples, BorderLayout.WEST);
demoFrame.add(addTitle("Full Name", new JScrollPane(fullNameList)), BorderLayout.EAST);
// Superhero Table
JTable superHeroTable = new JTable();
FCMTableModel superTableModel = new FCMTableModel(heroes, SuperHero#getFirstName(), SuperHero#getLastName(), SuperHero#getHeroName(), SuperHero#getFirstAppearance());
superHeroTable.setModel(superTableModel);
dateRenderer.setOpaque(true);
dateRenderer.setFont(UIManager.getFont("Table.font"));
dateRenderer.setHorizontalAlignment(JLabel.CENTER);
TableColumn dateColumn = superHeroTable.getColumn(SuperHero#getFirstAppearance().getName());
// in-line cell renderer for the date column of the superhero table
dateColumn.setCellRenderer(#(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column){
if(isSelected){
dateRenderer.setBackground(UIManager.getColor("Table.selectionBackground"));
}else{
dateRenderer.setBackground(UIManager.getColor("Table.background"));
}
dateRenderer.setText(sdfDateColumn.format((Date) value));
return dateRenderer;
});
demoFrame.add(addTitle("Super Heroes", new JScrollPane(superHeroTable)));
demoFrame.setVisible(true);
}
/**
* Wraps the component in a JPanel with a titled border
*/
private JComponent addTitle(String title, JComponent target) {
JPanel borderPanel = new JPanel();
target.setPreferredSize(new Dimension(100,200));
borderPanel.setLayout(new BorderLayout());
borderPanel.setBorder(BorderFactory.createTitledBorder(title));
borderPanel.add(target);
return borderPanel;
}
/**
* @return builds the superhero data
*/
public List buildData() {
ArrayList data = new ArrayList();
data.add(new SuperHero("Steve", "Rogers", "Captian America", "3-1-1941"));
data.add(new SuperHero("Tony", "Stark", "Iron Man", "3-1-1963"));
data.add(new SuperHero("Peter", "Parker", "Spider-Man", "8-1-1962"));
data.add(new SuperHero("Reed", "Richards", "Mr. Fantastic", "11-1-1961"));
data.add(new SuperHero("Norrin", "Radd", "Silver Surfer", "3-1-1966"));
data.add(new SuperHero("Robbie", "Baldwin", "Speedball", "1-1-1988"));
data.add(new SuperHero("Luke", "Cage", "Power Man", "6-1-1972"));
data.add(new SuperHero("Vance", "Astro", "Captian Astro", "1-1-1988"));
return data;
}
/**
* Superhero - used as an example bean for this demonstration
*/
private static class SuperHero {
// fields should not normally be public, but these are exposed to
// demonstrate the FCMFieldListModel class
public String firstName;
public String lastName;
public String heroName;
private Date firstAppearance;
private SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
public SuperHero(String firstName, String lastName, String heroName,
String date) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.heroName = heroName;
try {
this.firstAppearance = sdf.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
}
public String getFullName() {
return firstName + " " + lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getHeroName() {
return heroName;
}
public void setHeroName(String heroName) {
this.heroName = heroName;
}
public Date getFirstAppearance() {
return firstAppearance;
}
public void setFirstAppearance(Date firstAppearance) {
this.firstAppearance = firstAppearance;
}
}
/**
* Wraps a list of elements and exposes one field to the list model
* interface
*
* @param
*/
private class FCMFieldListModel extends AbstractListModel {
private List backingList;
private Field targetField;
public FCMFieldListModel(List data, Field target) {
backingList = data;
targetField = target;
}
@Override
public Object getElementAt(int index) {
try {
return targetField.get(backingList.get(index));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getSize() {
return backingList.size();
}
}
/**
* Wraps a list of elements and exposes one method to the list model
* interface
*
* @param
*/
private class FCMMethodListModel extends AbstractListModel {
private List backingList;
private Method targetMethod;
public FCMMethodListModel(List data, Method target) {
backingList = data;
targetMethod = target;
}
@Override
public Object getElementAt(int index) {
try {
Object item = backingList.get(index);
return targetMethod.invoke(item);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
@Override
public int getSize() {
return backingList.size();
}
}
/**
* Wraps a list of elements and a list of methods. The methods define the
* columns and the elements define the rows.
*
* @param
*/
private class FCMTableModel extends AbstractTableModel {
private List backingDataList;
private List methodList;
public FCMTableModel(List data, Method... getters) {
methodList = Arrays.asList(getters);
backingDataList = data;
}
@Override
public Class getColumnClass(int columnIndex) {
return methodList.get(columnIndex).getReturnType();
}
@Override
public String getColumnName(int column) {
return methodList.get(column).getName();
}
@Override
public int getColumnCount() {
return methodList.size();
}
@Override
public int getRowCount() {
return backingDataList.size();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
return methodList.get(columnIndex).invoke(
backingDataList.get(rowIndex));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
}