?
Solved

program stalling?

Posted on 2003-03-01
4
Medium Priority
?
301 Views
Last Modified: 2011-09-20
Hi,

There is a problem with the following program, and I am pretty certain its with the onArrow method, which is called from the mousePressed method in the Lines4 class.   The program stalls when I click anywhere on the application.   What I am trying to do with the onArrow method is that if I click on any of the blue dots it will tell me that I have.   Thought I had it done correctly, but obviously not!!  
Any help,   and why does the program just stall?  If it is not working should it not give me an error, I dont think it is in an infinite loop or anything?

Thanks

PS Sorry I have only 25 points left in my account!


CODE:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Lines4 extends JFrame implements MouseListener, MouseMotionListener {

    private int startx = 200;
    private int starty = 200;
    static int numPoints;

    private JLabel statusBar;
    private Road roads[];

    private static final int roadLength = 100;
    static final int circleRadius = 4;

    private Road movingRoad;


    public Lines4() {
        super("Lines4");

        String ret = JOptionPane.showInputDialog("How many roads are there?");
        numPoints = Integer.parseInt( ret );
        double factor = 2.0 * Math.PI / ( numPoints  ) ;

        roads = new Road[numPoints];

        for (int i=0; i<numPoints; i++){
            int x = (int)( roadLength * Math.cos( factor * i ) );
            int y = (int)( roadLength * Math.sin( factor * i ) );
            roads[i] = new Road( i, startx, starty, circleRadius, startx+x, starty+y);
        }

        addMouseListener(this);
        addMouseMotionListener(this);
        statusBar = new JLabel();
        getContentPane().add(statusBar, BorderLayout.SOUTH);
    }

    public void paint( Graphics g ) {
        g.clearRect( 0, 0, getWidth(), getHeight() );
        for (int i=0; i<roads.length; i++) {
            roads[i].draw( g );
        }
    }

    // MouseListener Event Handlers
    public void mouseClicked( MouseEvent e ){
        statusBar.setText( "Clicked at [" + e.getX() +
                     ", " + e.getY() + "]" );
    }
    public void mousePressed( MouseEvent e ){
        statusBar.setText( "Pressed at [" + e.getX() +
                     ", " + e.getY() + "]" );

        for (int i=0; i<roads.length; i++) {
            if ( roads[i].onCircle( e.getX(), e.getY() ) ) {
                movingRoad = roads[i];

            }
        }
        if (!Road.onArrow(e.getX(), e.getY() )){
            System.out.println("On arrow");
        }
    }

    public void mouseReleased( MouseEvent e ){
        statusBar.setText( "Released at [" + e.getX() + ", " + e.getY() + "]" );
        movingRoad = null;
    }

    public void mouseEntered( MouseEvent e ){
        statusBar.setText( "Mouse in window" );
    }

    public void mouseExited( MouseEvent e ){
        statusBar.setText( "Mouse outside window" );
    }

    // MouseMotionListener event handlers
    public void mouseDragged( MouseEvent e ){
        statusBar.setText( "Dragged at [" + e.getX() +
                     ", " + e.getY() + "]" );

        if ( movingRoad != null ) {
            movingRoad.x = e.getX();
            movingRoad.y = e.getY();
            repaint();
        }
    }

    public void mouseMoved( MouseEvent e ) {
        statusBar.setText( "Moved at [" + e.getX() +
                     ", " + e.getY() + "]" );
    }


    public static void main( String args[] ) {
        Lines4 app = new Lines4();
        app.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        app.setSize( 400, 400 );
        app.setVisible( true );
    }
}



import java.awt.Color;
import java.awt.Graphics;
import java.awt.*;

class Road {

    private int index;
    private int startx, starty, radius;
    int x, y;
    static int ab[][];
    static int a, b, abr;

    Road( int index, int startx, int starty, int radius, int x, int y) {
        this.index = index;
        this.startx = startx;
        this.starty = starty;
        this.radius = radius;
        this.x = x;
        this.y = y;

    }

    void draw( Graphics g ) {

        g.setColor( Color.black );
        g.drawLine( startx, starty, x, y );
        g.drawString("R"+(index+1), x+radius, y+radius );
        g.setColor( Color.red );
        g.fillOval( x-radius/2, y-radius/2, radius*2, radius*2 );
        g.setColor(Color.blue);
        drawArrows(g, startx, starty, x, y, index);

    }

    boolean onCircle( int mouseX, int mouseY ) {
        int xdiff = mouseX-x;
        int ydiff = mouseY-y;

        return ( xdiff*xdiff + ydiff*ydiff <= radius*radius );
    }

    static boolean onArrow( int mouseX, int mouseY ) {
        boolean isOnArrow = false;

        for (int i = 0; i<ab.length; i++){
            a = ab[i][0];
            b = ab[i][1];
            int xdiff = mouseX-a;
            int ydiff = mouseY-b;

            while (!isOnArrow){
                isOnArrow = ( xdiff*xdiff + ydiff*ydiff <= Lines4.circleRadius*Lines4.circleRadius );
            }
        }
        return isOnArrow;
    }






    public void drawArrows(Graphics g, int x_1, int y_1, int x_2, int y_2, int index) {

        // this will be the distance of the arrows from the line
        int d = 12;

        // excentricity, if you decide to move the arrows around :)
        int e = 0;

        // arrays to contain the result coords
        int[] x = new int[4];
        int[] y = new int[4];
        ab = new int[Lines4.numPoints * 2][2];

        // diffs between the coords
        float dX = x_1 - x_2;
        float dY = y_1 - y_2;

        // the projections of your 1/4 of the line length arrows
        // on the line itself
        float x1 = (float) (x_1 - dX*1.5/4);
        float x2 = (float) (x_2 + dX*1.5/4);
        float y1 = (float) (y_1 - dY*1.5/4);
        float y2 = (float) (y_2 + dY*1.5/4);

        // length of the line
        float l = (float) Math.sqrt(dX*dX + dY*dY);

        if (l >= 0.01) {
            float sa = dY/l;
            float ca = dX/l;

            x[0] = (int) ((float)x1 + ((float)d/2 - e)*sa);
            y[0] = (int) ((float)y1 - ((float)d/2 - e)*ca);
            ab[index][0] = x[0];
            ab[index][1] = y[0];

            x[1] = (int) ((float)x1 + (-(float)d/2 - e)*sa);
            y[1] = (int) ((float)y1 - (-(float)d/2 - e)*ca);

            x[2] = (int) ((float)x2 + (-(float)d/2 - e)*sa);
            y[2] = (int) ((float)y2 - (-(float)d/2 - e)*ca);
            ab[index + 1][0] = x[2];
            ab[index + 1][1] = y[2];

            x[3] = (int) ((float)x2 + ((float)d/2 - e)*sa);
            y[3] = (int) ((float)y2 - ((float)d/2 - e)*ca);

            System.out.println(ab[index][0] + " " + ab[index][1]);
            System.out.println(ab[index+1][0] + " " + ab[index+1][1]);

        }

        // draw the 2 arrows
        g.drawPolygon(getArrow(x[0], y[0], x[3], y[3], 10, 5,0.5));
        g.drawPolygon(getArrow(x[2], y[2], x[1], y[1], 10, 5,0.5));
        g.fillOval(x[0] - radius/2, y[0] - radius/2, radius*2, radius*2);
        g.fillOval(x[2] - radius/2, y[2] - radius/2, radius*2, radius*2);
    }

   
    public Polygon getArrow(int x1, int y1, int x2, int y2, int headsize, int difference, double factor) {
        int[] crosslinebase = getArrowHeadLine(x1, y1, x2, y2, headsize);
        int[] headbase = getArrowHeadLine(x1, y1, x2, y2, headsize - difference);
        int[] crossline = getArrowHeadCrossLine(crosslinebase[0], crosslinebase[1], x2, y2, factor);

        Polygon head = new Polygon();

        head.addPoint(headbase[0], headbase[1]);
        head.addPoint(crossline[0], crossline[1]);
        head.addPoint(x2, y2);
        head.addPoint(crossline[2], crossline[3]);
        head.addPoint(headbase[0], headbase[1]);
        head.addPoint(x1, y1);

        return head;
    }

    public int[] getArrowHeadLine(int xsource, int ysource,int xdest,int ydest, int distance) {
        int[] arrowhead = new int[2];
        int headsize = distance;

        double stretchfactor = 0;
        stretchfactor = 1 - (headsize/(Math.sqrt(((xdest-xsource)*(xdest-xsource))+((ydest-ysource)*(ydest-ysource)))));

        arrowhead[0] = (int) (stretchfactor*(xdest-xsource))+xsource;
        arrowhead[1] = (int) (stretchfactor*(ydest-ysource))+ysource;

        return arrowhead;
    }

    public int[] getArrowHeadCrossLine(int x1, int x2, int b1, int b2, double factor) {
        int [] crossline = new int[4];

        int x_dest = (int) (((b1-x1)*factor)+x1);
        int y_dest = (int) (((b2-x2)*factor)+x2);

        crossline[0] = (int) ((x1+x2-y_dest));
        crossline[1] = (int) ((x2+x_dest-x1));
        crossline[2] = crossline[0]+(x1-crossline[0])*2;
        crossline[3] = crossline[1]+(x2-crossline[1])*2;
        return crossline;
    }

}
0
Comment
Question by:qwerty1977
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 4

Accepted Solution

by:
funnyveryfunny earned 75 total points
ID: 8048293
hi,

I've just looked at your onArrow( int mouseX, int mouseY ) method and the problem is within its while loop, i.e:

>>>>while (!isOnArrow){
               isOnArrow = ( xdiff*xdiff + ydiff*ydiff <=  Lines4.circleRadius*Lines4.circleRadius );

               // I've added this line for testing
               System.out.print(" loopin mad ");
           }

It's obvious one the first run, the condition of the while loop is always true (since you've set isOnArrow = false).
Also on the first run yr

a = ab[i][0]; = 0
b = ab[i][1]; = 0

so xdiff and ydiff are same as that of the mouse coordinates (x,y). So you can image what would happen when you've clicked on for example coord(233,100)!!!

Having broken down into details how yr method is executed, my next point is WHY A WHILE LOOP. Why would you want to looping round like mad on the the same thing that doesn't change at all after each iteration!!!!

So either eliminate yr while loop (this will stop yr loopin maddog) or rethink yr:

>>> isOnArrow = ( xdiff*xdiff + ydiff*ydiff <= Lines4.circleRadius*Lines4.circleRadius );

again.
0
 

Author Comment

by:qwerty1977
ID: 8056320
Thanks for your help, had an idea it was something to do with the while loop, so took it out, and replaced it with the code

static boolean onArrow( int mouseX, int mouseY ) {
        boolean isOnArrow = false;

        for (int i = 0; i<ab.length; i++){
            a = ab[i][0];
            b = ab[i][1];
            int xdiff = mouseX-a;
            int ydiff = mouseY-b;


            isOnArrow = ( xdiff*xdiff + ydiff*ydiff <= Lines4.circleRadius*Lines4.circleRadius );
            if (isOnArrow){
                i = ab.length + 1;
            }

        }
        return isOnArrow;
    }







0
 
LVL 4

Expert Comment

by:funnyveryfunny
ID: 8057039
Hi qwerty1977,

Thank you for your acceptance to my answer. For future reference, would you personally prefer having a detailed answer, one that is closer to a solution, or a general direction to the problem??

I personally don't care much about the points but I do care that my learning process is fully shared with others. This is why I've asked you.

Again thank you.
0
 

Author Comment

by:qwerty1977
ID: 8057476
I, personally, would prefer one close that is closer to a solution, but that maybe laziness on my part!!!   Even though I think it is good to have a solution in front of you, that I can work through and understand myself, as that is the way I prefer learning!
0

Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
Suggested Courses
Course of the Month15 days, 10 hours left to enroll

741 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question