package com.customfit.ctg.view; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.beans.*; import java.io.*; import javax.swing.*; /** * StarRatingPanel is a rating voting JPanel that displays a number of * stars for scoring something. * * @author David */ public class StarRatingPanel extends JComponent implements Icon, Serializable { PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); // ActionMap actionMap = new ActionMap(); /** * Number of stars to use. */ private int scale = 1; public static final String PROP_SCALE = "scale"; /** * Number of stars to score. */ private int score = 0; public static final String PROP_SCORE = "score"; /** * Boolean that indicates whether or not the star panel is editable. * * When true, the panel will let the user click to change the rating * or right click to remove the rating. * * When false, no changes are permitted by the user. */ private boolean editable = true; public static final String PROP_EDITABLE = "editable"; /** * Holds the star-off.png icon. */ private ImageIcon imageIconStarOff; /** * Holds the star-on.png icon. */ private ImageIcon imageIconStarOn; /** * Creates a new StarRatingPanel, which displays a number of * stars for scoring something. */ public StarRatingPanel() { super(); initComponents(); this.imageIconStarOff = new ImageIcon(getClass().getResource("/art/export/star-off.png")); this.imageIconStarOn = new ImageIcon(getClass().getResource("/art/export/star-on.png")); this.setPreferredSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.score, this.imageIconStarOff.getIconHeight())); this.setMinimumSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.score, this.imageIconStarOff.getIconHeight())); this.setMaximumSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.score, this.imageIconStarOff.getIconHeight())); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { addMouseListener(new java.awt.event.MouseAdapter() { public void mouseEntered(java.awt.event.MouseEvent evt) { formMouseEntered(evt); } public void mouseExited(java.awt.event.MouseEvent evt) { formMouseExited(evt); } public void mousePressed(java.awt.event.MouseEvent evt) { formMousePressed(evt); } }); addMouseMotionListener(new java.awt.event.MouseMotionAdapter() { public void mouseMoved(java.awt.event.MouseEvent evt) { formMouseMoved(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 18, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGap(0, 17, Short.MAX_VALUE) ); }// </editor-fold>//GEN-END:initComponents /** * Returns the score value for a given mouse polling position. * * @param evt MouseEvent * * @return The score value for a given mouse polling position. */ private int mousePositionToScoreValue(java.awt.event.MouseEvent evt) { return new Double(Math.ceil(new Integer(evt.getX()).doubleValue() / new Integer(this.imageIconStarOff.getIconWidth()).doubleValue())).intValue(); } private void formMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseEntered if (this.editable) this.paintScore(this, this.getGraphics(), 0, 0, mousePositionToScoreValue(evt)); }//GEN-LAST:event_formMouseEntered private void formMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseMoved if (this.editable) this.paintScore(this, this.getGraphics(), 0, 0, mousePositionToScoreValue(evt)); }//GEN-LAST:event_formMouseMoved private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed if (this.editable) { //if right click, erase the score if (evt.getButton() != MouseEvent.BUTTON1) { this.score = 0; this.repaint(); } //otherwise set the score else this.score = mousePositionToScoreValue(evt); } }//GEN-LAST:event_formMousePressed private void formMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseExited //make sure we are on the right star if (this.editable) this.repaint(); }//GEN-LAST:event_formMouseExited // Variables declaration - do not modify//GEN-BEGIN:variables // End of variables declaration//GEN-END:variables /** * Gets the scale currently in use. (The number of stars displayed.) * @return The scale. */ public int getScale() { return this.scale; } /** * Sets the scale to use. (The number of stars to display.) * * @param scale The scale. */ public void setScale(int scale) { int oldScale = scale; this.scale = scale; this.setPreferredSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.scale, this.imageIconStarOff.getIconHeight())); this.setMinimumSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.scale, this.imageIconStarOff.getIconHeight())); this.setMaximumSize(new Dimension(this.imageIconStarOff.getIconWidth()*this.scale, this.imageIconStarOff.getIconHeight())); this.repaint(); this.propertyChangeSupport.firePropertyChange(PROP_SCALE, Integer.valueOf(oldScale), Integer.valueOf(scale)); } /** * Gets the current score. (Number of stars checked.) * * @return The score. */ public int getScore() { return this.score; } /** * Sets the current score. (Number of stars checked.) * * @param score The score. */ public void setScore(int score) { int oldScore = score; this.score = score; this.repaint(); this.propertyChangeSupport.firePropertyChange(PROP_SCORE, Integer.valueOf(oldScore), Integer.valueOf(this.score)); } /** * Sets the current score by rating. * * @param percentage Percentage of checked stars. */ public void setRating(double percentage) { this.setScore(new Double(Math.ceil(this.scale * percentage)).intValue()); } /** * Gets the rating by dividing score / scale. * * @param percentage Percentage of checked stars. */ public double getRating() { return new Integer(this.score).doubleValue() / new Integer(this.scale).doubleValue(); } /** * Gets Boolean that indicates whether or not the star panel is editable. * * When true, the panel will let the user click to change the rating * or right click to remove the rating. * * @return Boolean that indicates whether or not the star panel is editable. */ public boolean isEditable() { return editable; } /** * Sets Boolean that indicates whether or not the star panel is editable. * * When true, the panel will let the user click to change the rating * or right click to remove the rating. * * @param editable Boolean that indicates whether or not the star panel is editable. */ public void setEditable(boolean editable) { boolean oldEditable = this.editable; this.editable = editable; this.propertyChangeSupport.firePropertyChange(PROP_EDITABLE, Boolean.valueOf(oldEditable), Boolean.valueOf(this.editable)); } /** * Paints the current rating on the panel. * * @param g A valid Graphics instance. */ @Override public void paint(Graphics g) { paintScore(this, g, 0, 0, this.score); } /** * Paints any rating on the panel. * * @param g A valid Graphics instance. * @param score The rating to redraw. */ public void paintScore(Component c, Graphics g, int x, int y, int score) { //do superclass first super.paint(g); //for each star for (int s = 0; s < this.scale; s++) { //is checked if (s < score) { //draw bright star if (this.imageIconStarOn != null) imageIconStarOn.paintIcon(c, g, x + s*this.imageIconStarOn.getIconWidth(), y); } //isn't checked else { //draw gray star if (this.imageIconStarOff != null) imageIconStarOff.paintIcon(c, g, x + s*this.imageIconStarOff.getIconWidth(), y); } } } @Override public void paintIcon(Component c, Graphics g, int x, int y) { paintScore(c, g, x, y, this.score); } @Override public int getIconWidth() { return this.scale * this.imageIconStarOff.getIconWidth(); } @Override public int getIconHeight() { return this.imageIconStarOff.getIconHeight(); } public ImageIcon toImageIcon() { //first create an image Image image = new BufferedImage(this.getIconWidth(), this.getIconHeight(), BufferedImage.TYPE_INT_ARGB); this.paintIcon(this, image.getGraphics(), 0, 0); return new ImageIcon(image); } public void addStarRatingPropertyChangeSupport(PropertyChangeListener listener) { this.propertyChangeSupport.addPropertyChangeListener(listener); } public void addStarRatingPropertyChangeSupport(String property, PropertyChangeListener listener) { this.propertyChangeSupport.addPropertyChangeListener(property, listener); } public void removeStarRatingPropertyChangeSupport(PropertyChangeListener listener) { this.propertyChangeSupport.removePropertyChangeListener(listener); } // public void addStarRatingActionSupport(String action, ActionListener listener) // { // this.actionMap. addPropertyChangeListener(property, listener); // } // // public void removeStarRatingActionSupport(ActionListener listener) // { // this.actionMap..removePropertyChangeListener(listener); // } }