/** * Example 9: Team Browser * * This example shows how selections work with an MCList * * There are a number components in this application. The MVCList on * the left is using the DefaultObjectPrinter which sends toString() to * each object. The MVCList on the right is using an ObjectPrinter that * we created to display the names a little differently. There are also * two Buttons for populating the list, which, by the way, both MVCList * components share. */ import java.awt.*; import java.util.Vector; import com.bdnm.awt.*; import com.bdnm.mvc.*; public class Example9 extends java.applet.Applet { /** * Layout the panel here and hold onto the model * behind the list. */ public void init() { // Just give the examples a distinctive background setBackground(new Color(128,128,192)); // Our layouts are getting too elaborate for the simple // layout managers. Use a different one. FractionalLayout flay = new FractionalLayout(); setLayout(flay); // This is the team list MVCList teamList = new MVCList(); add(teamList); flay.setConstraint(teamList, new FrameConstraint(0.0,0,0.0,0,0.5,0,0.3,0)); // This is the player list MVCList playerList = new MVCList(); add(playerList); flay.setConstraint(playerList, new FrameConstraint(0.0,0,0.3,0,0.5,0,1.0,0)); // Now add the read-only field for the Player's name. Since it is a read-only // field, I can give it an ObjectPrinter which will send toString() to the // object sitting in the model. MVCTextField playerName = new MVCTextField(); playerName.setEditable(false); playerName.converter(new DefaultObjectPrinter()); add(playerName); flay.setConstraint(playerName, new FrameConstraint(0.5,10,0.0,10,1.0,-10,0.0,30)); // And a field for the shooting percentage, which is a float Label label = new Label("Shooting %:", Label.RIGHT); add(label); flay.setConstraint(label, new FrameConstraint(0.5,10,0.0,40,0.75,-5,0.0,60)); MVCTextField shootingPercentage = new MVCTextField(); shootingPercentage.setType(MVCTextField.TYPE_FLOAT); add(shootingPercentage); flay.setConstraint(shootingPercentage, new FrameConstraint(0.75,5,0.0,40,1.0,-10,0.0,60)); // First, wire the player list to the team list playerList.setModel(new SelectionInList(new PlayersValueAdaptor(teamList.getModel().selectionHolder()), new ValueHolder(null))); // This object is a SelectionHolder - something that always holds onto // the selection of the list. SelectionHolder selHolder = playerList.getModel().selectionHolder(); // Next, we make the model behind the player name field just // be whatever the current selection is playerName.setModel(selHolder); // And we make the shooting percentage field show the attribute // for whoever is currently selected. shootingPercentage.setModel(new ShootingPercentageValueAdaptor(selHolder)); // Now that everything is all wired together, set the contents of the team list. Vector teams = new Vector(2); teams.addElement(Team.bulls()); teams.addElement(Team.magic()); teamList.getModel().list(teams); } /** * This is just a method to make this run standalone. */ public static void main(String args[]) { Frame f = new Frame("Example 9"); Example9 applet = new Example9(); applet.init(); f.add("Center", applet); f.pack(); f.resize(f.preferredSize()); f.show(); } } /** * This is a ValueAdaptor which expects a ValueModel on a Player object as * its model. It will send the getters and setters for shootingPercentage * to convert a Player to a Float and vice-versa. */ class ShootingPercentageValueAdaptor extends ValueAdaptor { /** * Construct an instance with a reference model. * * @param aModel a reference model */ public ShootingPercentageValueAdaptor(ValueModel aModel) { super(aModel); } /** * The value coming from my model can be modified. Return * the modified value that will be forwarded on. * * @param aValue the value of my model * @return the value which I represent */ protected Object valueFromModel(Object aValue) { return (aValue == null) ? null : new Float(((Player) aValue).shootingPercentage()); } /** * The value to set to my model can be modified. Return the * modified value that my model will be set to. * * @param aValue the value to I should represent * @return the value which my model should be set to */ protected Object valueToModel(Object aValue) { Player curPlayer = (Player) getModel().getValue(); if (curPlayer != null) { curPlayer.shootingPercentage(((Number) aValue).floatValue()); } return curPlayer; // no change to the model } } /** * This is a ValueAdaptor which expects a ValueModel on a Team object as * its model. It appears to have the value of a Vector of Players. */ class PlayersValueAdaptor extends ValueAdaptor { /** * Construct an instance with a reference model. * * @param aModel a reference model */ public PlayersValueAdaptor(ValueModel aModel) { super(aModel); } /** * The value coming from my model can be modified. Return * the modified value that will be forwarded on. * * @param aValue the value of my model * @return the value which I represent */ protected Object valueFromModel(Object aValue) { if (aValue == null) return new Vector(); Player[] players = ((Team) aValue).players(); Vector newList = new Vector(players.length); for (int i = 0; i < players.length; ++i) { newList.addElement(players[i]); } return newList; } /** * The value to set to my model can be modified. Return the * modified value that my model will be set to. * * @param aValue the value to I should represent * @return the value which my model should be set to */ protected Object valueToModel(Object aValue) { // This should never be called throw new RuntimeException("Should not be setting players!"); } }