package arcade.view; import java.awt.Color; import java.awt.Component; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.ResourceBundle; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.WindowConstants; import util.ImageHelper; import arcade.controller.Controller; import arcade.games.Comment; import arcade.games.GameInfo; import arcade.view.forms.payment.PaymentSelection; /** * Detail View is the view to display the detailed information about a game. * It serves as a extension of a game snapshot where only a thumbnail, the name * and the rating of the game is displayed. * * Detial view has a thumbnail, the game's name, author, genre, rating. It also * provides previous comments users input and a description the game programmers * write when publishing. * * Furthermore, it also provides users the ability to comment and rate this game. * * Finally, the actual game is also trigger here, or it allows a user to buy * the game and after purchase, the game would be put into the user's game center. * * * @author David Liu, Ellango Jothimurugesan * */ public class DetailView extends JFrame { private static final Integer[] RATINGS = {1,2,3,4,5}; private static final String GAME_TITLE_FONT_TAIL = "</font></font></b></html>"; private static final String GAME_TITLE_FONT_HEADER = "<html><b><font color = gray><font size = 6>"; private static final String PLAY_IMAGE_URL = "/src/arcade/resources/images/PlayIcon.jpg"; private static final String COMMENT_AREA_CONTENT_TYPE = "text/html"; private static final String DESCRIPTION = "Description"; private static final String COMMENTS = "Comments"; private static final String USER_DIR = "user.dir"; private static final String SUBMIT = "Submit"; private static final String PRICE = " Price: "; private static final String BUY = "BUY"; private static final String HTML_BOLD_HEADER = "<b>"; private static final String HTML_BOLD_TAIL = "</b>"; private static final String NEWLINE = "\n"; private static final String HTML_NEWLINE = "<br>"; private static final int DESCRIPTION_SECTION_BACKGROUND_OPACITY = 20; private static final int WINDOW_Y_COORDINATE = 100; private static final int WINDOW_X_COORDINATE = 100; private static final int DESCRIPTION_COLUMN = 1; private static final int DESCRIPTION_ROWS = 10; private static final int WINDOW_WIDTH = 600; private static final int WINDOW_HEIGHT = 600; private ResourceBundle myResources; private GameInfo myGameInfo; private JPanel myContentPanel; private Controller myController; /** * Create and initialized the detail view * @param info * @param resources * @param controller */ public DetailView (GameInfo info, ResourceBundle resources, Controller controller) { myController = controller; setBackground(Color.WHITE); myGameInfo = info; myResources = resources; myContentPanel = (JPanel) getContentPane(); setLayout(new BoxLayout(myContentPanel, BoxLayout.PAGE_AXIS)); myContentPanel.setAlignmentX(JComponent.LEFT_ALIGNMENT); setTitle(resources.getString(TextKeywords.TITLE)); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); createTheBasicInfoPanel(); Color c = makeLightGray(); createAndConfigureTheDescriptionSection(c); createCommentSection(); createCommentingAndRatingArea(); setBounds(WINDOW_X_COORDINATE, WINDOW_Y_COORDINATE, WINDOW_WIDTH, WINDOW_HEIGHT); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setVisible(true); } /** * Create the area for users to write comments and rate this game. * */ private void createCommentingAndRatingArea() { final JTextArea commentsWriter = new JTextArea(3, 30); commentsWriter.setBackground(Color.LIGHT_GRAY); commentsWriter.setWrapStyleWord(true); commentsWriter.setLineWrap(true); final JComboBox ratingBox = new JComboBox(RATINGS); JButton submitButton = new JButton(SUBMIT); submitButton.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent arg0) { double rating = (Integer)ratingBox.getSelectedItem() + 0.0;//(Double)ratingBox.getSelectedItem(); myController.commentAndRateGame(commentsWriter.getText(), rating, myGameInfo.getName()); commentsWriter.setText(""); } }); JPanel subPanel = new JPanel(); subPanel.add(commentsWriter); subPanel.add(ratingBox); myContentPanel.add(subPanel); myContentPanel.add(submitButton); } /** * Create the comment section with a message saying "comment" and a area * to display all the comments users have previously input for this game. * */ private void createCommentSection() { JLabel comments = new JLabel(COMMENTS); comments.setBackground(Color.gray); myContentPanel.add(comments); JEditorPane commentsContent = new JEditorPane(); commentsContent.setEditable(false); commentsContent.setContentType(COMMENT_AREA_CONTENT_TYPE); constructCommentAreaContent(commentsContent); JScrollPane commentPane = new JScrollPane(commentsContent); myContentPanel.add(commentPane); } /** * Create the description section with a message "description" and a * description of the game provided by the game programmer when publishing. * * @param c */ private void createAndConfigureTheDescriptionSection(Color c) { JLabel description = new JLabel(DESCRIPTION); description.setBackground(c); description.setAlignmentX(Component.LEFT_ALIGNMENT); JTextArea descriptionContent = new JTextArea(myGameInfo.getDescription(), DESCRIPTION_ROWS, DESCRIPTION_COLUMN); descriptionContent.setLineWrap(true); descriptionContent.setWrapStyleWord(true); descriptionContent.setEditable(false); descriptionContent.setBackground(c); JScrollPane descriptionPane = new JScrollPane(descriptionContent); myContentPanel.add(description); myContentPanel.add(descriptionPane); } /** * Create the basic info area. It includes a thumbnail for the game, the * game's name, author, genre, overall rating and a play or buy button * base on whether the user is current in store or game center. * */ private void createTheBasicInfoPanel() { JPanel basicInfoPanel = new JPanel(); ImageIcon icon = myGameInfo.getThumbnail(); Image scaledImage = ImageHelper.getScaledImage(icon, 160); JLabel picture = new JLabel(new ImageIcon(scaledImage)); basicInfoPanel.add(picture); basicInfoPanel.add(createSubPanelForBasicInfoPanel(myGameInfo)); if (myController.getGamesPurchased().contains(myGameInfo)) basicInfoPanel.add(createThePlayButton()); else basicInfoPanel.add(createThePurchaseButton()); myContentPanel.add(basicInfoPanel); } /** * Helper function, used to adjust the grayness of background for * game description area. * @return */ private Color makeLightGray() { int r = Color.GRAY.getRed(); int g = Color.gray.getGreen(); int b = Color.GRAY.getBlue(); Color c = new Color(r, g, b, DESCRIPTION_SECTION_BACKGROUND_OPACITY); return c; } /** * Create the buy button which will trigger the payment view and methods. * */ private JButton createThePurchaseButton() { JButton buyButton = new JButton(BUY+ NEWLINE + PRICE + myGameInfo.getPrice()); buyButton.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent arg0) { new PaymentSelection(myController, myResources, myGameInfo); } }); return buyButton; } /** * Create the play button which starts the game the user selects. * */ private JButton createThePlayButton() { String localDirectory = System.getProperty(USER_DIR); ImageIcon playButtonIcon = new ImageIcon(localDirectory + PLAY_IMAGE_URL); JButton playButton = new JButton(playButtonIcon); playButton.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { myController.playGame(myGameInfo); } }); return playButton; } /** * Helper method used to create a JPanel with the game title, game genre, * the author, and the overall rating. * * Used to help better organize the view. * * @param info * @return */ private JPanel createSubPanelForBasicInfoPanel(GameInfo info) { JPanel subPanelForBasicInfo = new JPanel(); subPanelForBasicInfo.setLayout(new BoxLayout(subPanelForBasicInfo, BoxLayout.PAGE_AXIS)); JLabel title = new JLabel(GAME_TITLE_FONT_HEADER + myGameInfo.getName() + GAME_TITLE_FONT_TAIL); JLabel genre = new JLabel(myGameInfo.getGenre()); JLabel author = new JLabel(myGameInfo.getAuthor()); JLabel rating = new RatingIcons().makeLabel((int)info.getRating()); subPanelForBasicInfo.add(title); subPanelForBasicInfo.add(genre); subPanelForBasicInfo.add(author); subPanelForBasicInfo.add(rating); return subPanelForBasicInfo; } /** * Pulling previous comments from the database and fill the area with * comments. Comments are formatted with the user name in bold. It also * shows what rating the user gave to the game * */ private void constructCommentAreaContent (JEditorPane commentPane) { List<Comment> comments = myGameInfo.getComments(); StringBuilder sb = new StringBuilder(); for (Comment comment : comments) { sb.append(HTML_BOLD_HEADER + comment.getUser() + HTML_BOLD_TAIL); sb.append(HTML_NEWLINE); sb.append(new RatingIcons().makeHTMLText((int)comment.getRating())); sb.append(HTML_NEWLINE); sb.append(comment.getComment()); sb.append(HTML_NEWLINE); sb.append(HTML_NEWLINE); } commentPane.setText(sb.toString()); } }