From 3f8b7b6ffcb86966be6f254352d4d6ad54cfdebc Mon Sep 17 00:00:00 2001 From: tjc <tjc@ee4ac58c-ac51-4696-9907-e4b3aa274f04> Date: Thu, 1 Jul 2004 12:43:21 +0000 Subject: [PATCH] fix mouse drag git-svn-id: svn+ssh://svn.internal.sanger.ac.uk/repos/svn/pathsoft/artemis/trunk@1691 ee4ac58c-ac51-4696-9907-e4b3aa274f04 --- uk/ac/sanger/artemis/components/Plot.java | 454 ++++++++++++---------- 1 file changed, 257 insertions(+), 197 deletions(-) diff --git a/uk/ac/sanger/artemis/components/Plot.java b/uk/ac/sanger/artemis/components/Plot.java index 8ee213ebe..b2d177b15 100644 --- a/uk/ac/sanger/artemis/components/Plot.java +++ b/uk/ac/sanger/artemis/components/Plot.java @@ -20,27 +20,89 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/Plot.java,v 1.1 2004-06-09 09:47:11 tjc Exp $ + * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/Plot.java,v 1.2 2004-07-01 12:43:21 tjc Exp $ **/ package uk.ac.sanger.artemis.components; -import uk.ac.sanger.artemis.*; +import uk.ac.sanger.artemis.Options; import uk.ac.sanger.artemis.plot.*; import java.awt.*; import java.awt.event.*; -import javax.swing.*; +import javax.swing.JPanel; +import javax.swing.JComponent; +import javax.swing.JScrollPane; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenuItem; +import javax.swing.JScrollBar; +import javax.swing.JPopupMenu; /** * This class implements a simple plot component. * * @author Kim Rutherford - * @version $Id: Plot.java,v 1.1 2004-06-09 09:47:11 tjc Exp $ + * @version $Id: Plot.java,v 1.2 2004-07-01 12:43:21 tjc Exp $ **/ -public abstract class Plot extends JPanel { +public abstract class Plot extends JPanel +{ + + /** + * The drawing area for this component. + **/ + private JComponent canvas = null; + + /** + * A scroll bar for changing the window size. + **/ + private JScrollBar window_changer = null; + + /** + * The height of the font used in this component. + **/ + private int font_height; + + /** + * Off screen image used for double buffering when drawing the canvas. + **/ + private Image offscreen; + + /** + * The object that will generate the value we plot in this component. + **/ + private Algorithm algorithm; + + /** + * If true then a scale line will be drawn at the bottom of the graph when + * drawScaleLine () is called. + **/ + private boolean draw_scale; + + /** + * Set to true if drawMultiValueGraph () should call recalculateValues (). + * It is reset to false by recalculateValues (). + **/ + protected boolean recalculate_flag = true; + + /** + * The x position of the last click or -1 if the user hasn't clicked + * anywhere yet or the user clicked outside the graph. + **/ + private int cross_hair_position = -1; + + /** + * The x position of the start of the last mouse drag or -1 if the user + * hasn't clicked anywhere yet or the user clicked outside the graph. + **/ + private int drag_start_position = -1; + + /** + * A vector of those objects listening for PlotMouse events. + **/ + final private java.util.Vector listener_list = new java.util.Vector (); + /** * Create a new plot component. * @param algorithm The object that will generate the values we plot in @@ -48,7 +110,8 @@ public abstract class Plot extends JPanel { * @param draw_scale If true then a scale line will be drawn at the bottom * of the graph. **/ - public Plot (Algorithm algorithm, boolean draw_scale) { + public Plot (Algorithm algorithm, boolean draw_scale) + { this.algorithm = algorithm; this.draw_scale = draw_scale; @@ -56,62 +119,62 @@ public abstract class Plot extends JPanel { setFont (font); FontMetrics fm = getFontMetrics (font); - font_height = fm.getHeight (); + font_height = fm.getHeight(); - setLayout(new BorderLayout ()); + setLayout(new BorderLayout()); final int MAX_WINDOW; - if (getAlgorithm ().getDefaultMaxWindowSize () != null) { - MAX_WINDOW = getAlgorithm ().getDefaultMaxWindowSize ().intValue (); - } else { + if(getAlgorithm().getDefaultMaxWindowSize () != null) + MAX_WINDOW = getAlgorithm().getDefaultMaxWindowSize().intValue(); + else MAX_WINDOW = 500; - } final int MIN_WINDOW; - if (getAlgorithm ().getDefaultMinWindowSize () != null) { + if(getAlgorithm ().getDefaultMinWindowSize () != null) MIN_WINDOW = getAlgorithm ().getDefaultMinWindowSize ().intValue (); - } else { + else MIN_WINDOW = 5; - } final int START_WINDOW; - if (getAlgorithm ().getDefaultWindowSize () == null) { + if(getAlgorithm().getDefaultWindowSize() == null) START_WINDOW = 10; - } else { - START_WINDOW = getAlgorithm ().getDefaultWindowSize ().intValue (); - } + else + START_WINDOW = getAlgorithm().getDefaultWindowSize().intValue(); window_changer = new JScrollBar (Scrollbar.VERTICAL); window_changer.setValues (START_WINDOW, SCROLL_NOB_SIZE, MIN_WINDOW, MAX_WINDOW + SCROLL_NOB_SIZE); - if (MAX_WINDOW >= 50) { + if (MAX_WINDOW >= 50) window_changer.setBlockIncrement (MAX_WINDOW/50); - } else { + else window_changer.setBlockIncrement (1); - } - window_changer.addAdjustmentListener (new AdjustmentListener () { - public void adjustmentValueChanged(AdjustmentEvent e) { + window_changer.addAdjustmentListener(new AdjustmentListener() + { + public void adjustmentValueChanged(AdjustmentEvent e) + { recalculate_flag = true; repaintCanvas (); } }); - addComponentListener (new ComponentAdapter () { - public void componentShown(ComponentEvent e) { + addComponentListener(new ComponentAdapter() + { + public void componentShown(ComponentEvent e) + { recalculate_flag = true; repaintCanvas (); } }); - add (window_changer, "East"); + add(window_changer, "East"); - createCanvas (); + createCanvas(); - getCanvas ().setBackground (Color.white); + getCanvas().setBackground (Color.white); } final int SCROLL_NOB_SIZE = 10; @@ -119,7 +182,8 @@ public abstract class Plot extends JPanel { /** * Return the algorithm that was passed to the constructor. **/ - public Algorithm getAlgorithm () { + public Algorithm getAlgorithm() + { return algorithm; } @@ -127,19 +191,23 @@ public abstract class Plot extends JPanel { * Return the current value of the window size, as set by the * window_changer scrollbar. **/ - public int getWindowSize () { + public int getWindowSize() + { return window_changer.getValue (); } /** * Create the canvas object for this BasePlot and add it to the component. **/ - private void createCanvas () { - canvas = new JComponent () { + private void createCanvas() + { + canvas = new JComponent() + { /** * Set the offscreen buffer to null as part of invalidation. **/ - public void invalidate() { + public void invalidate() + { super.invalidate(); offscreen = null; } @@ -147,66 +215,75 @@ public abstract class Plot extends JPanel { /** * Override update to *not* erase the background before painting */ - public void update(Graphics g) { + public void update(Graphics g) + { paint(g); } /** * Paint the canvas. */ - public void paint(Graphics g) { + public void paint(Graphics g) + { paintCanvas (g); } }; - final MouseListener mouse_listener = - new MouseAdapter () { + final MouseListener mouse_listener = new MouseAdapter() + { /** * Listen for mouse press events so that we can do a popup menu and a * crosshair. **/ - public void mousePressed (MouseEvent event) { - if (event.isPopupTrigger () || event.isMetaDown ()) { - final JComponent parent = (JComponent) event.getSource (); - - final JPopupMenu popup = new JPopupMenu ("Plot Options"); + public void mousePressed(MouseEvent event) + { + if(event.isPopupTrigger() || event.isMetaDown()) + { + final JComponent parent = (JComponent)event.getSource(); + final JPopupMenu popup = new JPopupMenu("Plot Options"); final JCheckBoxMenuItem scaling_toggle = new JCheckBoxMenuItem ("Scaling"); - scaling_toggle.setState (getAlgorithm ().scalingFlag ()); - scaling_toggle.addItemListener (new ItemListener () { - public void itemStateChanged (ItemEvent _) { + scaling_toggle.setState(getAlgorithm ().scalingFlag ()); + scaling_toggle.addItemListener(new ItemListener () + { + public void itemStateChanged (ItemEvent _) + { getAlgorithm ().setScalingFlag (scaling_toggle.getState ()); recalculate_flag = true; - repaintCanvas (); + repaintCanvas(); } }); - popup.add (scaling_toggle); - - popup.addSeparator (); + popup.add(scaling_toggle); + popup.addSeparator(); final JMenuItem max_window_size = new JMenuItem ("Maximum Window Size:"); popup.add (max_window_size); - final int [] window_sizes = { + final int [] window_sizes = + { 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000 }; - for (int i = 0 ; i < window_sizes.length ; ++i) { + for(int i = 0 ; i < window_sizes.length ; ++i) + { final int size = i; - JMenuItem window_size_item = new JMenuItem (" " + window_sizes[i]); + JMenuItem window_size_item = new JMenuItem(" " + window_sizes[i]); - window_size_item.addActionListener (new ActionListener () { - public void actionPerformed (ActionEvent _) { + window_size_item.addActionListener(new ActionListener() + { + public void actionPerformed (ActionEvent _) + { final int new_maximum = window_sizes[size]; - if (new_maximum > window_changer.getMinimum ()) { - window_changer.setMaximum (new_maximum + SCROLL_NOB_SIZE); + if(new_maximum > window_changer.getMinimum ()) + { + window_changer.setMaximum(new_maximum + SCROLL_NOB_SIZE); recalculate_flag = true; repaintCanvas (); } @@ -217,26 +294,27 @@ public abstract class Plot extends JPanel { } parent.add (popup); - popup.show (parent, event.getX (), event.getY ()); - } else { + } + else + { final int point_x = event.getPoint ().x; final int point_y = event.getPoint ().y; - if (point_y > getLabelHeight ()) { + if(point_y > getLabelHeight ()) + { cross_hair_position = point_x; drag_start_position = point_x; - } else { + } + else cancelCrossHairs (); - } - if (event.getClickCount () == 2) { - fireDoubleClickEvent (); - } else { - fireClickEvent (); - } + if(event.getClickCount() == 2) + fireDoubleClickEvent(); + else + fireClickEvent(); - repaintCanvas (); + repaintCanvas(); } } }; @@ -244,21 +322,23 @@ public abstract class Plot extends JPanel { canvas.addMouseListener (mouse_listener); final MouseMotionListener mouse_motion_listener = - new MouseMotionAdapter () { + new MouseMotionAdapter() + { + public void mouseDragged (MouseEvent event) + { + if(isMenuTrigger(event)) + return; - public void mouseDragged (MouseEvent event) { - final int point_x = event.getPoint ().x; - final int point_y = event.getPoint ().y; + final int point_x = event.getPoint().x; + final int point_y = event.getPoint().y; - if (point_y > getLabelHeight ()) { + if(point_y > getLabelHeight()) cross_hair_position = point_x; - } else { - cancelCrossHairs (); - } - - fireDragEvent (); + else + cancelCrossHairs(); - repaintCanvas (); + fireDragEvent(); + repaintCanvas(); } }; @@ -267,15 +347,30 @@ public abstract class Plot extends JPanel { add (canvas, "Center"); } + /** + * Return true if and only if the given MouseEvent (a mouse press) should + * pop up a JPopupMenu. + **/ + private boolean isMenuTrigger(final MouseEvent event) + { + if(event.isPopupTrigger() || + (event.getModifiers() & InputEvent.BUTTON3_MASK) != 0) + return true; + else + return false; + } + /** * Call mouseClick () on each of the PlotMouseListener objects in the * listener list. **/ - private void fireClickEvent () { - for (int i = 0 ; i < listener_list.size () ; ++i) { + private void fireClickEvent() + { + for (int i = 0 ; i < listener_list.size() ; ++i) + { final PlotMouseListener listener = - (PlotMouseListener) listener_list.elementAt (i); - listener.mouseClick (getPointPosition (cross_hair_position)); + (PlotMouseListener)listener_list.elementAt(i); + listener.mouseClick(getPointPosition(cross_hair_position)); } } @@ -283,12 +378,14 @@ public abstract class Plot extends JPanel { * Call mouseDragged () on each of the PlotMouseListener objects in the * listener list. **/ - private void fireDragEvent () { - for (int i = 0 ; i < listener_list.size () ; ++i) { + private void fireDragEvent() + { + for(int i = 0; i < listener_list.size(); ++i) + { final PlotMouseListener listener = - (PlotMouseListener) listener_list.elementAt (i); - listener.mouseDrag (getPointPosition (drag_start_position), - getPointPosition (cross_hair_position)); + (PlotMouseListener)listener_list.elementAt(i); + listener.mouseDrag(getPointPosition(drag_start_position), + getPointPosition(cross_hair_position)); } } @@ -296,11 +393,13 @@ public abstract class Plot extends JPanel { * Call mouseDoubleClick () on each of the PlotMouseListener objects in the * listener list. **/ - private void fireDoubleClickEvent () { - for (int i = 0 ; i < listener_list.size () ; ++i) { + private void fireDoubleClickEvent() + { + for(int i = 0; i < listener_list.size(); ++i) + { final PlotMouseListener listener = - (PlotMouseListener) listener_list.elementAt (i); - listener.mouseDoubleClick (getPointPosition (cross_hair_position)); + (PlotMouseListener)listener_list.elementAt (i); + listener.mouseDoubleClick(getPointPosition(cross_hair_position)); } } @@ -308,8 +407,9 @@ public abstract class Plot extends JPanel { * Adds the given listener to receive mouse events from this object. * @param l the listener. **/ - public void addPlotMouseListener (final PlotMouseListener listener) { - listener_list.addElement (listener); + public void addPlotMouseListener(final PlotMouseListener listener) + { + listener_list.addElement(listener); } /** @@ -317,8 +417,9 @@ public abstract class Plot extends JPanel { * mouse events from this object. * @param l the listener. **/ - public void removePlotMouseListener (final PlotMouseListener listener) { - listener_list.removeElement (listener); + public void removePlotMouseListener(final PlotMouseListener listener) + { + listener_list.removeElement(listener); } /** @@ -326,57 +427,58 @@ public abstract class Plot extends JPanel { * double buffering when drawing the canvas. * @param g The Graphics object of the canvas. **/ - private void paintCanvas (final Graphics g) { - if (!isVisible ()) { + private void paintCanvas(final Graphics g) + { + if(!isVisible()) return; - } - final int canvas_width = canvas.getSize ().width; - final int canvas_height = canvas.getSize ().height; + final int canvas_width = canvas.getSize().width; + final int canvas_height = canvas.getSize().height; - if (canvas_height <= 0 || canvas_width <= 0) { + if(canvas_height <= 0 || canvas_width <= 0) + { // there is no point painting a zero width canvas return; } - if (offscreen == null) { - offscreen = createImage (canvas_width, - canvas_height); - } + if(offscreen == null) + offscreen = createImage(canvas_width, + canvas_height); Graphics og = offscreen.getGraphics (); - og.setClip (0, 0, canvas_width, canvas_height); + og.setClip(0, 0, canvas_width, canvas_height); - og.setColor (new Color (240, 240, 240)); + og.setColor(new Color (240, 240, 240)); - og.fillRect (0, 0, canvas.getSize ().width, canvas.getSize ().height); + og.fillRect(0, 0, canvas.getSize().width, canvas.getSize().height); // Redraw the graph on the canvas using the algorithm from the // constructor. - drawMultiValueGraph (og); + drawMultiValueGraph(og); - drawLabels (og); + drawLabels(og); - g.drawImage (offscreen, 0, 0, null); - og.dispose (); + g.drawImage(offscreen, 0, 0, null); + og.dispose(); } /** * Return the canvas x position of the last click or -1 if the user hasn't * clicked anywhere yet. **/ - protected int getCrossHairPosition () { - if (cross_hair_position >= getCanvas ().getSize ().width) { + protected int getCrossHairPosition() + { + if(cross_hair_position >= getCanvas().getSize().width) return -1; - } else { + else return cross_hair_position; - } } /** * Force this component to stop drawing crosshairs. **/ - protected void cancelCrossHairs () { + protected void cancelCrossHairs() + { cross_hair_position = -1; drag_start_position = -1; } @@ -389,9 +491,9 @@ public abstract class Plot extends JPanel { * @param start The base on the left * @param end The base on the right **/ - protected void drawScaleLine (final Graphics g, - final int start, final int end) { - + protected void drawScaleLine(final Graphics g, + final int start, final int end) + { final int canvas_width = canvas.getSize ().width; final int canvas_height = canvas.getSize ().height; @@ -408,17 +510,17 @@ public abstract class Plot extends JPanel { final int index_of_first_label; - if (possible_index_of_first_label == 0) { + if (possible_index_of_first_label == 0) index_of_first_label = 1; - } else { + else index_of_first_label = possible_index_of_first_label; - } final int index_of_last_label = end / base_label_spacing; for (int i = index_of_first_label ; i <= index_of_last_label ; - ++i) { + ++i) + { final String label_string = String.valueOf ((int)(i * base_label_spacing)); @@ -453,7 +555,8 @@ public abstract class Plot extends JPanel { final int step_size, final int window_size, final int total_unit_count, final int start_position, - final float [] plot_values) { + final float [] plot_values) + { final float residues_per_pixel = (float) total_unit_count / canvas.getSize ().width; @@ -471,7 +574,8 @@ public abstract class Plot extends JPanel { final int number_of_values = plot_values.length; - for (int i = 0 ; i < number_of_values - 1 ; ++i) { + for(int i = 0; i<number_of_values - 1; ++i) + { final int start_residue = window_size / 2 + i * step_size + start_position; final int end_residue = @@ -513,7 +617,8 @@ public abstract class Plot extends JPanel { **/ protected void drawGlobalAverage (final Graphics g, final float min_value, - final float max_value) { + final float max_value) + { final Float average = getAlgorithm ().getAverage (); if (average != null) { @@ -554,7 +659,8 @@ public abstract class Plot extends JPanel { * window size in the bottom left. * @param g The object to draw into. **/ - private void drawLabels (final Graphics g) { + private void drawLabels (final Graphics g) + { g.setColor (Color.black); g.drawString (getAlgorithm ().getAlgorithmName () + " Window size: " + @@ -568,8 +674,9 @@ public abstract class Plot extends JPanel { * then draws them onto the canvas. The min_value is drawn at the bottom * right, max_value at the top right. **/ - protected void drawMinMax (final Graphics g, - final float min_value, final float max_value) { + protected void drawMinMax(final Graphics g, + final float min_value, final float max_value) + { g.setColor (Color.black); final int canvas_width = canvas.getSize ().width; @@ -604,9 +711,11 @@ public abstract class Plot extends JPanel { * @param label_pos The position on the line at which the label should be * drawn (0 is nearest the top). **/ - protected void drawCrossHair (final Graphics g, final int x_position, - final String label, final int label_pos) { - if (x_position >= 0) { + protected void drawCrossHair(final Graphics g, final int x_position, + final String label, final int label_pos) + { + if (x_position >= 0) + { g.drawLine (x_position, getLabelHeight (), x_position, canvas.getSize ().height); @@ -618,14 +727,16 @@ public abstract class Plot extends JPanel { /** * Return the JComponent of this Plot. **/ - protected JComponent getCanvas () { + protected JComponent getCanvas() + { return canvas; } /** * Call repaint () on the canvas object. **/ - protected void repaintCanvas () { + protected void repaintCanvas() + { canvas.repaint (); } @@ -644,80 +755,29 @@ public abstract class Plot extends JPanel { /** * Return the amount of vertical space (in pixels) to use for the scale. **/ - private int getScaleHeight () { - if (draw_scale) { - return getFontHeight () + 2; - } else { + private int getScaleHeight() + { + if (draw_scale) + return getFontHeight() + 2; + else return 0; - } } /** * Return the height in algorithm name and label line (returns the font * height plus a small amount). **/ - private int getLabelHeight () { - return getFontHeight () + 2; + private int getLabelHeight() + { + return getFontHeight() + 2; } /** * Return the height in pixels of the current font. **/ - private int getFontHeight () { + private int getFontHeight() + { return font_height; } - /** - * The drawing area for this component. - **/ - private JComponent canvas = null; - - /** - * A scroll bar for changing the window size. - **/ - private JScrollBar window_changer = null; - - /** - * The height of the font used in this component. - **/ - private int font_height; - - /** - * Off screen image used for double buffering when drawing the canvas. - **/ - private Image offscreen; - - /** - * The object that will generate the value we plot in this component. - **/ - private Algorithm algorithm; - - /** - * If true then a scale line will be drawn at the bottom of the graph when - * drawScaleLine () is called. - **/ - private boolean draw_scale; - - /** - * Set to true if drawMultiValueGraph () should call recalculateValues (). - * It is reset to false by recalculateValues (). - **/ - protected boolean recalculate_flag = true; - - /** - * The x position of the last click or -1 if the user hasn't clicked - * anywhere yet or the user clicked outside the graph. - **/ - private int cross_hair_position = -1; - - /** - * The x position of the start of the last mouse drag or -1 if the user - * hasn't clicked anywhere yet or the user clicked outside the graph. - **/ - private int drag_start_position = -1; - - /** - * A vector of those objects listening for PlotMouse events. - **/ - final private java.util.Vector listener_list = new java.util.Vector (); } -- GitLab