Link to home
Start Free TrialLog in
Avatar of qwerty1977
qwerty1977

asked on

program stalling?

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;
    }

}
ASKER CERTIFIED SOLUTION
Avatar of funnyveryfunny
funnyveryfunny

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of qwerty1977
qwerty1977

ASKER

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;
    }







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.
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!