Java: Example - Raise.java
|
This program program was inspired by a Gore-Bush ballots in Florida.
The paintComponent method looks too complicated and
should be improved. Also, there's no need to redraw all the fixed
elements; these should be drawn only once. So many programs,
so little time.
|
// Raise.java - Ask employee if they want a raise.
// Example of mouse listeners.
// 2000-12-01 ... 2002-02-19
// Fred Swartz
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
////////////////////////////////////////////////////////////////////// Raise
public class Raise {
//================================================================= main
public static void main(String[] args) {
JFrame w = new RaiseWindow();
w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
w.setVisible(true);
}//end main
}//endclass Raise
//////////////////////////////////////////////////////////////// RaiseWindow
class RaiseWindow extends JFrame {
private SurveyForm survey; // "component" of the survey form.
//========================================================== constructor
public RaiseWindow() {
// Create components
survey = new SurveyForm();
JButton resetButton = new JButton("Reset");
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
survey.reset(false);
}
});
// Build title
JLabel title = new JLabel("Want a Raise?", JLabel.CENTER);
title.setFont(new Font("Serif", Font.BOLD, 48));
title.setForeground(Color.white);
JPanel titlePanel = new JPanel();
titlePanel.setBackground(Color.blue);
titlePanel.add(title);
// Layout components
Container content = this.getContentPane();
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
content.add(titlePanel);
content.add(survey);
content.add(resetButton);
this.setTitle("Employee Survey");
this.setResizable(false);
this.pack();
}//end constructor
}//endclass RaiseWindow
/////////////////////////////////////////////////////////// class SurveyForm
class SurveyForm extends JPanel implements MouseMotionListener {
private boolean finished = false; // set true after button selected
private int buttonX;
private int buttonY;
// The mouse coordinates are set by the mouse listeners.
// They must be instance variables so that paintComponent can
// use them in calculating the button position if necessary.
private int mouseX = 0;
private int mouseY = 0;
//========================================================== constructor
public SurveyForm() {
this.setBackground(Color.white);
this.setPreferredSize(new Dimension(300, 230));
this.setFont(new Font("Serif", Font.BOLD, 48));
this.addMouseMotionListener(this);
}//end constructor
//================================================================ reset
public void reset(boolean fin) {
// Called whenever the status of the form should be reset.
finished = fin;
this.repaint(); // repaint after any change that might show
}//end
//======================================================= paintComponent
public void paintComponent(Graphics g) {
super.paintComponent(g);
final int NAME_X = 20; // x coord of names
final int NORAISE_Y = 80; // y coord of NoRaise button
final int RAISE_Y = NORAISE_Y + 100;
final int MARK_X = 240; // x coord of buttons
final int RADIUS = 16; // button radius
final int CRITICAL_DIST = 3 * RADIUS;
final int CENTER_X = MARK_X; // x coord of buttons
final int CENTER_Y = RAISE_Y - 16; // default y coord of noraise
final int leftEdge = CENTER_X - CRITICAL_DIST;
final int rightEdge = CENTER_X + CRITICAL_DIST;
final int topEdge = CENTER_Y - CRITICAL_DIST;
final int bottomEdge = CENTER_Y + CRITICAL_DIST;
// Draw choices
g.setColor(Color.black);
g.drawString("No Raise", NAME_X, NORAISE_Y);
g.drawString("Raise" , NAME_X, RAISE_Y);
// Check to see if near "No Raise" button, and "select" it if so.
if (mouseY > (NORAISE_Y-CRITICAL_DIST) && mouseY < (NORAISE_Y+CRITICAL_DIST)
&& mouseX > leftEdge && mouseX < rightEdge) {
finished = true; // Cause No Raise radio button to be "selected"
}
if (finished) { // Draw selected No Raise button and fixed Raise button
g.fillOval(MARK_X-RADIUS, NORAISE_Y-16-RADIUS, 2*RADIUS, 2*RADIUS);
g.drawOval(CENTER_X-RADIUS, CENTER_Y-RADIUS, 2*RADIUS, 2*RADIUS);
} else {
// Draw empty No Raise button (doesn't depend on mouse position)
g.drawOval(MARK_X-RADIUS, NORAISE_Y-16-RADIUS, 2*RADIUS, 2*RADIUS);
// Draw Raise button (depends on mouse position)
buttonX = CENTER_X;// Assume normal position; change if mouse is near
buttonY = CENTER_Y;
if (mouseX > leftEdge && mouseX < rightEdge
&& mouseY > topEdge && mouseY < bottomEdge) {
// mouse is near the Raise button, so we may move it
int mdx = CENTER_X - mouseX;
int mdy = CENTER_Y - mouseY;
if (mdx == 0)
mdx = 1; // don't let mouse appear at center
if (mdy == 0)
mdy = 1; // don't let mouse appear at center
// compute distance of mouse from center.
double mouseDist = Math.sqrt(mdx*mdx + mdy*mdy);
if (mouseDist < CRITICAL_DIST) {
// It's within the critical radius.
double bdist = CRITICAL_DIST - mouseDist;// button to center
double ratio = bdist / mouseDist;
buttonX = CENTER_X + (int)(ratio * mdx);
buttonY = CENTER_Y + (int)(ratio * mdy);
}
}
g.drawOval(buttonX-RADIUS, buttonY-RADIUS, 2*RADIUS, 2*RADIUS);
}
}//end paintComponent
//================================================== mouseMoved listener
public void mouseMoved(MouseEvent e) {
this.mouseX = e.getX();
this.mouseY = e.getY();
this.repaint();
}//end mouseMoved
//================================================== mouseMoved listener
public void mouseDragged(MouseEvent e) {
this.mouseX = e.getX();
this.mouseY = e.getY();
this.repaint();
}//end mouseDragged
}//end class SurveyForm