import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.util.*; class JogDial extends JComponent implements MouseListener, MouseMotionListener { public static final int WIDTH = 400; public static final int HEIGHT = 200; public static final int OFFSET = 10; public static final int BAR_THICKNESS = 15; public static final int LINE_DIFFERENCE = 7; public static final int BEAD_WIDTH = 10; public static final int BEAD_HEIGHT = 25; protected int[] values = {-2,-1,0,1,2}; protected int bead_x = WIDTH/2; protected int bead_y = OFFSET + (BAR_THICKNESS/2); protected int scroll_rate = 0; protected Vector listeners = new Vector(); protected int id = 0; public JogDial() { super(); this.addMouseListener(this); this.addMouseMotionListener(this); } protected boolean beadSelected = false; public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) { Rectangle bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH, BEAD_HEIGHT); beadSelected = bead.contains(e.getX(),e.getY()); } public void mouseReleased(MouseEvent e) { if (beadSelected) { beadSelected = false; this.snapBeadCenter(); fire(0); } } public void mouseMoved(MouseEvent e) {} public void mouseDragged(MouseEvent e) { if (beadSelected) { int old_bead_x = bead_x; //// this code can be written better... //// you can practice writing this better yourself :) if ((e.getX() >= this.OFFSET) && (e.getX() < this.WIDTH - OFFSET)) { Rectangle old_bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); this.bead_x = e.getX(); Rectangle bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); repaint(old_bead); repaint(bead); if (scroll_rate != getValue(bead_x)) fire(getValue(bead_x)); } //// the following code was added...to have the bead all the way to the left //// or all the way to the right when the mouse is moved off the component in //// that direction else if (e.getX() >= this.WIDTH - this.OFFSET) { Rectangle old_bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); this.bead_x = this.WIDTH - this.OFFSET - 1; Rectangle bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); repaint(old_bead); repaint(bead); if (scroll_rate != getValue(bead_x)) fire(getValue(bead_x)); } else if (e.getX() < this.OFFSET) { Rectangle old_bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); this.bead_x = this.OFFSET; Rectangle bead = new Rectangle(bead_x - (this.BEAD_WIDTH/2), bead_y -(this.BEAD_HEIGHT/2), BEAD_WIDTH+1, BEAD_HEIGHT+1); repaint(old_bead); repaint(bead); if (scroll_rate != getValue(bead_x)) fire(getValue(bead_x)); } } } public void addScrollListener(ScrollListener l) { listeners.addElement(l); } public void removeScrollListener(ScrollListener l) { listeners.removeElement(l); } public void fire(int value) { //// TODO: //// //// think about how this can be done in a way that //// would not affect the user's interaction with the component //// when one of the scroll listener takes a long time //// handling the event. //// ScrollEvent e = new ScrollEvent(this,id++,value); for(int i=0; i