package project2; import javax.swing.*; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JScrollPane; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.Image; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import javax.swing.ListSelectionModel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.Component; import java.awt.Color; import java.awt.BorderLayout; import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.JTextArea; import java.util.ArrayList; /** A GUI interface for the Oracle Mall */ public class OracleMall extends JFrame implements IPublicInformation { private JList oracleChooser; // // private JScrollPane oracleScroller; private JComponent oracleInfoArea; //internal to the scrollbar private JComponent omenArea; //includes both the info panel and the result //omenInfoArea and omenResultArea are inside, but is not a top-level object private JPanel inputPanel; private JTextField inputText; private JTextArea inputResultMessage; private PublicOracle currentOracle = null; private PublicOracle[] oracleArray; private JComponent[] oracleInfoPanels; private /*Container*/ JComponent contentPane; static final Dimension screenDim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); /** Default width of the mall window*/ static final int omallDefaultWidth = (int) (0.9 * screenDim.width); /** Default height of the mall window */ static final int omallDefaultHeight = (int) (0.9 * screenDim.height); static final Dimension omallDefaultSize = new Dimension( omallDefaultWidth, omallDefaultHeight); /** Constructor. Create panels for each oracle, but don't show them. */ public OracleMall(PublicOracle[] inputOracleArray) { super(); this.setTitle("This is the Mall of the Oracles"); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.setSize(omallDefaultSize); contentPane = (JComponent) this.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.setMaximumSize(new Dimension( omallDefaultWidth, omallDefaultHeight)); contentPane.add(new JScrollPane(new PublicInfoPanel(this))); //prune deadwood from the input list ArrayList oList = new ArrayList(); for (int a = 0; a < inputOracleArray.length; a++) { //preserve only non-null entries if (inputOracleArray[a] != null) { oList.add(inputOracleArray[a]); } } //oracleArray = (PublicOracle[]) oList.toArray(); //syntax OK, but class cast exception oracleArray = new PublicOracle[oList.size()]; for (int i = 0; i < oList.size(); i++) { oracleArray[i] = (PublicOracle) oList.get(i); } //Set up the list box of oracles this.oracleChooser = new JList(oracleArray); this.oracleChooser.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //this.oracleScroller = new JScrollPane(oracleChooser); this.oracleChooser.addListSelectionListener(new ListListener()); this.oracleChooser.setMinimumSize( new Dimension(omallDefaultWidth/4, omallDefaultHeight/5)); this.contentPane.add(new JScrollPane(oracleChooser)); //Now create all the oracle panels, without adding them to main panel this.oracleInfoPanels = new JComponent[oracleArray.length]; for (int p = 0; p < oracleArray.length; p++) { PublicOracle thisOracle = oracleArray[p]; if (thisOracle == null) { oracleInfoPanels[p] = null; //shouldn't happen if array was pruned } else { oracleInfoPanels[p] = new JScrollPane(new PublicInfoPanel(thisOracle)); } } //Create the text input area, but don't show it this.inputPanel = new JPanel(); this.inputPanel.setLayout(new BorderLayout()); this.inputPanel.add(new JLabel("enter text here according to the instructions"), BorderLayout.NORTH); this.inputText = new JTextField(25); //argument is the number of columns this.inputText.addActionListener(new InputListener()); this.inputPanel.add(inputText,BorderLayout.CENTER); this.inputResultMessage = new JTextArea(); this.inputResultMessage.setFocusable(false); this.inputResultMessage.setBackground(new Color(240,240,245)); this.inputPanel.add(new JScrollPane(inputResultMessage), BorderLayout.SOUTH); this.inputPanel.setVisible(false); this.contentPane.add(inputPanel); //SwingUtils.setDim(this.contentPane); //SwingUtils.setDim(this); this.contentPane.revalidate(); //this.pack(); this.show(); this.oracleChooser.requestFocus(); //SwingUtils.setDim(this); //end OracleMall constructor } /** For the IPublicInformation interface.*/ public String getAuthor() { return "MD"; } public String getImageURLString() { String[] images = {"http://www.cs.washington.edu/images/sptm133.jpg", "http://lazowska.cs.washington.edu/sieg/siegfrontsm.jpg", "http://www.cs.washington.edu/images/cse_logo_133.gif" }; int iCount = images.length; int index = (int) (images.length * Math.random()); assert index >= 0 && index < images.length; String istring = images[index]; return istring; //return "http://www.cs.washington.edu/images/cse_logo_133.gif"; //return "http://lazowska.cs.washington.edu/sieg/siegfrontsm.jpg"; } public String getName() { return "The Oracle Mall"; } public String getObjectName() { return "The Oracle Mall"; } public String getInstructions() { return "From the list of oracles, click on the one you wish to invoke. " + "Further instructions will follow."; } public String getObjectDescription() { return "This mall is your one-stop shopping center for all your divination needs." + "Feel free to browse."; } public Color getColor() { return new Color(10, 100, 10); //a dark green } /** Inner listener class for the listbox. * Get the panel for this oracle and add it to the display panel. */ private class ListListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { if (OracleMall.this.omenArea != null) { OracleMall.this.omenArea.setVisible(false); } JList list = (JList) e.getSource(); int sIndex = list.getSelectedIndex(); OracleMall.this.currentOracle = OracleMall.this.oracleArray[sIndex]; assert OracleMall.this.currentOracle != null; if (OracleMall.this.oracleInfoArea != null) { //remove the old panel before showing another one OracleMall.this.contentPane.remove(OracleMall.this.oracleInfoArea); } JComponent oracleInfo = OracleMall.this.oracleInfoPanels[sIndex]; assert oracleInfo != null; OracleMall.this.oracleInfoArea = oracleInfo; OracleMall.this.contentPane.add( OracleMall.this.oracleInfoArea); OracleMall.this.oracleInfoArea.setVisible(true); OracleMall.this.oracleInfoArea.revalidate(); //SwingUtils.setDim(OracleMall.this.oracleInfoArea); OracleMall.this.inputText.setText(""); OracleMall.this.inputText.requestFocus(); OracleMall.this.inputResultMessage.setText(""); OracleMall.this.inputPanel.setVisible(true); OracleMall.this.contentPane.revalidate(); //ineffective? // OracleMall.this.pack(); //this worked OracleMall.this.repaint(); } //end ListListener } /** Listener for when the user hits ENTER on the text input.*/ class InputListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (OracleMall.this.omenArea != null) { //hide previous omen OracleMall.this.omenArea.setVisible(false); } OracleMall.this.inputResultMessage.setText(""); String inputTyped = OracleMall.this.inputText.getText(); boolean inputOK = OracleMall.this.currentOracle.checkRequestData(inputTyped); if (inputOK) { OracleMall.this.inputResultMessage.setForeground(Color.green); OracleMall.this.inputResultMessage.setText("The oracle accepts your request, " + "and has begun to study the entrails."); //Following line should be in a separate thread, as it could be long-running.*/ //Here is where we FINALLY invoke the oracle IOmen resultingOmen = (PublicOmen) OracleMall.this.currentOracle.searchEntrailsForOmen(inputTyped); if (resultingOmen == null) { OracleMall.this.inputResultMessage.setForeground(Color.red); OracleMall.this.inputResultMessage.setText( "The oracle has no omen for thee. " + "Despair and depart, or try again."); } else { //Got an omen back... tell about it. OracleMall.this.inputResultMessage.setForeground(Color.green); OracleMall.this.inputResultMessage.setText("An omen has been received."); //Display the omen in the omen area if (OracleMall.this.omenArea != null) { OracleMall.this.getContentPane().remove(OracleMall.this.omenArea); } JPanel tempomenArea = new JPanel(); //start afresh Dimension omenAreaDim = new Dimension(omallDefaultWidth, omallDefaultHeight/2); tempomenArea.setPreferredSize(omenAreaDim); { JComponent omenInfoPanel = new PublicInfoPanel( (IPublicInformation) resultingOmen); tempomenArea.add(new JScrollPane(omenInfoPanel)); } { String interpretation = resultingOmen.interpretInDetail(); JTextArea interpArea = new JTextArea(4, 20); interpArea.setText("Here followeth the detailed interpretation of the oracle:\n" + interpretation); tempomenArea.add(new JScrollPane(interpArea)); OracleMall.this.omenArea = new JScrollPane(tempomenArea); //OracleMall.this.omenArea = tempomenArea; } OracleMall.this.contentPane.add(OracleMall.this.omenArea); OracleMall.this.omenArea.setVisible(true); } } else { OracleMall.this.inputResultMessage.setForeground(Color.red); OracleMall.this.inputResultMessage.setText("The oracle rejects your request!" + " Depart in fear and shame, or try again."); } OracleMall.this.contentPane.revalidate(); //OracleMall.this.pack(); OracleMall.this.repaint(); } //end class InputListener } //end class OracleMall }