1

We are having a school project, where we are drawing a highly detailed map on a canvas using JavaFX and integrating Swing via JFXPanel. Everytime we open the application the canvas is black until either resized or any interaction with the canvas has taken place, for instance panning or zooming. I have been through the entire internet searching the error, but unfortunatly without luck.

Code Snippet:

public class CanvasViewNew extends Application {
private AnchorPane rootLayout;
private Stage primaryStage;
private Canvas canvas;

@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    Model model = new Model("Data/Data/cph.zip");
    canvas = new Canvas(model);

    new MouseController(canvas, model);
    SwingNode swingNode = new SwingNode();
    rootLayout = new AnchorPane();

    createSwingContent(swingNode);

    //Sets canvas to a prefered size.
    canvas.setPreferredSize(new Dimension(1000, 1000));

    //Creates and sets the scene to an AnchorPane.
    Scene scene = new Scene(rootLayout);

    //Adds the swingnode to the RootLayout.

    rootLayout.getChildren().addAll(swingNode);
    System.out.println(swingNode.getScene());
    primaryStage.setScene(scene);
    primaryStage.show();
    rootLayout.requestFocus();
    swingNode.requestFocus();
    swingNode.autosize();
    swingNode.resize(1000,1000);

    //Calls the panning and zoom methods in canvas, which enables the zooming and panning on canvas.
    canvas.pan(-model.getMinLon(), -model.getMaxLat());
    canvas.zoom((primaryStage.getWidth()) + 200 / (model.getMaxLon() - model.getMinLon()), 0, 0);
    canvas.zoomFactor = primaryStage.getWidth() / (model.getMaxLon() - model.getMinLon());
    canvas.minZoom = canvas.zoomFactor / 4;
    canvas.maxZoom = canvas.zoomFactor * 200;
        }

private void createSwingContent(SwingNode swingNode) {
    SwingUtilities.invokeLater(() -> {
        //  AnchorPane canvasPane = adjustSwingNode(swingNode);
        swingNode.setContent(canvas);
    });
}

public static void main(String args[]) {
    launch(args);
}

.

public class Canvas extends JFXPanel implements Observer {

private final Model model;
private boolean useAntiAliasing = false;
private AffineTransform transform = new AffineTransform();
private boolean drawingModeEnabled = false;
private final String drawingModeMessage = "Drawing Mode enabled";
private double fps = 0.0;
private KDTree.Rect searchRect;
private KDTreePath.Rect searchRectway;
private DrawTreeSplits splits;


public double maxZoom;
public double minZoom;
public double zoomFactor;

public Canvas(Model m) {
    this.model = m;
    model.addObserver(this);
    splits = new DrawTreeSplits(model.getWayTree(), model.getMinLon(), model.getMaxLon(), model.getMinLat(), model.getMaxLat());
    repaint();
}

@Override
public void paint(Graphics _g) {
    long t1 = System.nanoTime();
    Graphics2D g = (Graphics2D) _g;
    g.setStroke(new BasicStroke(Float.MIN_VALUE));
    if (drawingModeEnabled) {
        int width = g.getFontMetrics().stringWidth(drawingModeMessage);
        int height = g.getFontMetrics().getHeight();
        // draw string in red, reset to black afterwards.
        g.setPaint(Color.red);
        g.drawString(drawingModeMessage, getWidth() - width - 20, getHeight() - height - 10);
        g.setPaint(Color.black);
    }
    Rectangle2D viewRect = new Rectangle2D.Double(0, 0, getWidth(), getHeight());


    //Draw methods

    g.setBackground(new Color(152, 152, 152));

    g.setPaint(new Color(60, 149, 255));
    g.fill(viewRect);
    g.transform(transform);
    try {
        viewRect = transform.createInverse().createTransformedShape(viewRect).getBounds2D();
    } catch (NoninvertibleTransformException e) {
        e.printStackTrace();
    }

    if (useAntiAliasing) {
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
    }

    //draw split lines for FUN

    //draw Coastlines
    g.setPaint(new Color(237, 237, 237));
    for (Shape coastline : model.get(OSMWayType.COASTLINE)) {
        if (coastline.intersects(viewRect)) {
            g.fill(coastline);
        }
    }

    //draw unknown lines
   /* g.setStroke(new BasicStroke(0.00001f));
    g.setPaint(new Color(0, 0, 0));
    for (Shape line : model.get(OSMWayType.UNKNOWN)) {
        if (line.intersects(viewRect)) {
            g.draw(line);
        }
    }*/
    searchRect = new KDTree.Rect(viewRect.getMinX(), viewRect.getMinY(), viewRect.getMaxX(), viewRect.getMaxY());
    searchRectway = new KDTreePath.Rect(viewRect.getMinX(), viewRect.getMinY(), viewRect.getMaxX(), viewRect.getMaxY());
    if (zoomFactor > 2300)
        drawLandScapes(g);

    if (zoomFactor > 5000)
        drawOutlines(g);

    if (zoomFactor > 10000) {
        drawStructures(g);
        drawCityDetails(g);
    }

    if (zoomFactor > 7500)
        drawCityRoads(g);

    if (zoomFactor > 28000)
        drawCitySmallDetails(g);

    if (zoomFactor > 100)
        drawMainRoads(g);

    if (zoomFactor > 15000)
        drawCitySmallRoads(g);

    if (zoomFactor > 35000)
        drawPoints(g);

    //splits.paint(g);
    long t2 = System.nanoTime();
    fps = (fps + 1e9 / (t2 - t1)) / 2;
    g.setTransform(new AffineTransform());
    g.setColor(Color.WHITE);
    g.fillRect(5, 5, 80, 20);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
    g.setColor(Color.BLACK);
    g.drawRect(5, 5, 80, 20);
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.drawString(String.format("FPS: %.1f", fps), 10, 20);
}

private void drawMainRoads(Graphics2D g) {

    for (OSMWayPath shape : model.getHighWayTree().rangeSearch(searchRectway)) {

        //draw Highways
        if (shape.getType() == OSMWayType.HIGHWAY) {
            g.setStroke(new BasicStroke(0.00005f));
            g.setPaint(new Color(182, 63, 61));
            g.draw(shape);
        }
        //draw secondary highways
        if (shape.getType() == OSMWayType.SECONDARYHIGHWAY) {
            g.setStroke(new BasicStroke(0.0002f));
            g.setPaint(new Color(214, 183, 25));
            g.draw(shape);

        }
        //draw tertiary roads
        if (shape.getType() == OSMWayType.TERTIARY && zoomFactor > 400) {
            g.setStroke(new BasicStroke(0.0002f));
            g.setPaint(new Color(0, 255, 122));
            g.draw(shape);
        }
    }
}

private void drawOutlines(Graphics2D g) {
    for (OSMWayPath shape : model.getWayTree().rangeSearch(searchRectway)) {
        //draw residential area
        if (shape.getType() == OSMWayType.RESIDENTIALAREA) {
            g.setPaint(new Color(115, 115, 121));
            g.fill(shape);
        }

        //draw industrial area
        if (shape.getType() == OSMWayType.INDUSTRIALAREA) {
            g.setPaint(new Color(95, 94, 95));
            g.fill(shape);
        }

    }
}

private void drawLandScapes(Graphics2D g) {
    for (OSMWayPath shape : model.getWayTree().rangeSearch(searchRectway)) {

        //draw water
        if (shape.getType() == OSMWayType.WATER) {
            g.setPaint(new Color(60, 149, 255));
            g.fill(shape);
        }

        //draw forests
        if (shape.getType() == OSMWayType.FOREST) {
            g.setPaint(new Color(0, 102, 2));
            g.fill(shape);
        }

        //draw beaches
        if (shape.getType() == OSMWayType.BEACH) {
            g.setPaint(new Color(194, 178, 128));
            g.fill(shape);
        }

        //draw grass
        if (shape.getType() == OSMWayType.GRASS) {
            g.setPaint(new Color(0, 249, 2));
            g.fill(shape);
        }

        //draw sand areas
        if (shape.getType() == OSMWayType.SAND) {
            g.setPaint(new Color(194, 178, 128));
            g.fill(shape);
        }

        //draw nature reserves
        if (shape.getType() == OSMWayType.NATURERESERVE) {
            g.setPaint(new Color(0, 203, 2));
            g.fill(shape);
        }

        //draw woods
        if (shape.getType() == OSMWayType.WOOD) {
            g.setPaint(new Color(0, 156, 2));
            g.fill(shape);
        }

        //draw waterways
        if (shape.getType() == OSMWayType.WATERWAY) {
            g.setStroke(new BasicStroke(0.00004f));
            g.setPaint(new Color(60, 149, 255));
            g.draw(shape);
        }

        //draw golf courses
        if (shape.getType() == OSMWayType.GOLF) {
            g.setPaint(new Color(78, 156, 0));
            g.fill(shape);
        }
    }
}

private void drawPoints(Graphics2D g) {
    //draw points
    for (OSMPoint point : model.getPointTree().rangeSearch(searchRect)) {
        g.setPaint(new Color(0, 11, 255));
        if (point.getType() == OSMNodeType.STATION) {
            Rectangle2D.Double rect = new Rectangle2D.Double(point.getX(), point.getY(), 0.00010, 0.00010);
            g.fill(rect);
        }
        // draw cafes as points
        if (point.getType() == OSMNodeType.CAFE) {
            g.setPaint(new Color(211, 104, 16));
            Ellipse2D.Double cafe = new Ellipse2D.Double(point.getX(), point.getY(), 0.00004, 0.00004);
            g.fill(cafe);
        }

        //draw shops as points
        if (point.getType() == OSMNodeType.SHOP) {
            g.setPaint(new Color(31, 211, 17));
            Ellipse2D.Double shop = new Ellipse2D.Double(point.getX(), point.getY(), 0.00004, 0.00004);
            g.fill(shop);
        }
        //draw shops as points
        if (point.getType() == OSMNodeType.EATINGPLACE) {
            g.setPaint(new Color(47, 211, 210));
            Ellipse2D.Double eat = new Ellipse2D.Double(point.getX(), point.getY(), 0.00004, 0.00004);
            g.fill(eat);
        }
    }
}

private void drawCityRoads(Graphics2D g) {

    for (OSMWayPath shape : model.getWayTree().rangeSearch(searchRectway)) {
        if (shape.getType() == OSMWayType.RESIDENTIAL) {
            g.setStroke(new BasicStroke(0.00002f));
            g.setPaint(new Color(255, 255, 255));
            g.draw(shape);
        }

        //draw railroad
        if (shape.getType() == OSMWayType.RAIL) {
            g.setStroke(new BasicStroke(0.00003f));
            g.setPaint(new Color(198, 228, 26));
            g.draw(shape);
        }
    }
}

private void drawCitySmallRoads(Graphics2D g) {

    for (OSMWayPath shape : model.getWayTree().rangeSearch(searchRectway)) {
        //draw normal roads
        if (shape.getType() == OSMWayType.ROAD) {
            g.setStroke(new BasicStroke(0.00003f));
            g.setPaint(new Color(255, 255, 255));
            g.draw(shape);
        }

        //draw metro lines
        if (shape.getType() == OSMWayType.METRO) {
            //g.setStroke(new BasicStroke(0.00005f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL, 0.00007f, new float[]{0.00012f}, 0.0005f));
            g.setStroke(new BasicStroke(0.00005f));
            g.setPaint(new Color(194, 0, 7));
            g.draw(shape);
        }

        //draw bike roads
        if (shape.getType() == OSMWayType.BIKE) {
            //g.setStroke(new BasicStroke(0.00002f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0.00002f, new float[]{0.00003f}, 0f));
            g.setStroke(new BasicStroke(0.00001f));
            g.setPaint(new Color(19, 75, 214));
            g.draw(shape);
        }

        //draw footway roads
        if (shape.getType() == OSMWayType.FOOTWAY) {
            //g.setStroke(new BasicStroke(0.00001f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 0.00003f, new float[]{0.00003f}, 0f));
            g.setStroke(new BasicStroke(0.00001f));
            g.setPaint(new Color(214, 48, 46));
            g.draw(shape);
        }

        //draw paths
        if (shape.getType() == OSMWayType.PATH) {
            g.setStroke(new BasicStroke(0.00001f));
            g.setPaint(new Color(214, 48, 46));
            g.draw(shape);
        }
    }
}

private void drawCityDetails(Graphics2D g) {
    for (OSMWayPath shape : model.getCityDetailsTree().rangeSearch(searchRectway)) {

        //draw allotments
        if (shape.getType() == OSMWayType.ALLOTMENTS) {
            g.setPaint(new Color(141, 195, 30));
            g.fill(shape);
        }

        //draw parks
        if (shape.getType() == OSMWayType.PARK) {
            g.setPaint(new Color(29, 195, 0));
            g.fill(shape);
        }

        //draw gardens
        if (shape.getType() == OSMWayType.GARDEN) {
            g.setPaint(new Color(117, 195, 16));
            g.fill(shape);
        }

        //draw parkingLots
        if (shape.getType() == OSMWayType.PARKING) {
            g.setPaint(new Color(55, 70, 132));
            g.fill(shape);
        }
    }
}

private void drawCitySmallDetails(Graphics2D g) {
    for (OSMWayPath shape : model.getCityDetailsTree().rangeSearch(searchRectway)) {


        //draw pitches (sporting area)

        if (shape.getType() == OSMWayType.PITCH) {
            g.setPaint(new Color(138, 169, 182));
            g.fill(shape);
        }

        //draw Piers
        if (shape.getType() == OSMWayType.PIER) {
            g.setPaint(new Color(147, 80, 25));
            g.fill(shape);
        }

        //draw Piers
        if (shape.getType() == OSMWayType.PLAYGROUND) {
            g.setPaint(new Color(203, 123, 10));
            g.fill(shape);
        }
    }
}

private void drawStructures(Graphics2D g) {
    //draw buildings
    g.setStroke(new BasicStroke(0.00001f));
    for (OSMWayPath shape : model.getWayTree().rangeSearch(searchRectway)) {

        if (shape.getType() == OSMWayType.BUILDING) {
            g.setPaint(new Color(144, 144, 150));
            g.fill(shape);
        }

        //draw bridges
        if (shape.getType() == OSMWayType.BRIDGE) {
            g.setPaint(new Color(146, 142, 149));
            g.fill(shape);
        }
    }
}


/**
 * This method is called whenever the observed object is changed. An
 * application calls an <tt>Observable</tt> object's
 * <code>notifyObservers</code> method to have all the object's
 * observers notified of the change.
 *
 * @param o   the observable object.
 * @param arg an argument passed to the <code>notifyObservers</code>
 */
@Override
public void update(Observable o, Object arg) {
    repaint();
}

public void toggleAntiAliasing() {
    useAntiAliasing = !useAntiAliasing;
    repaint();
}

public void pan(double dx, double dy) {
    transform.preConcatenate(AffineTransform.getTranslateInstance(dx, dy));
    repaint();
}

public void zoomToCenter(double factor) {
    zoom(factor, -getWidth() / 2, -getHeight() / 2);
}

public void zoom(double factor, double x, double y) {
    if (factor < 1 && zoomFactor < minZoom) {
        System.out.println("You can't zoom anymore");
    } else if (factor > 1 && zoomFactor > maxZoom) {
        System.out.println("You can't zoom anymore");
    } else {
        zoomFactor *= factor;
        System.out.println(zoomFactor);
        pan(x, y);
        transform.preConcatenate(AffineTransform.getScaleInstance(factor, factor));
        pan(-x, -y);
        repaint();
    }

}

public void toggleDrawingMode() {
    drawingModeEnabled = !drawingModeEnabled;
}

public boolean inDrawingMode() {
    return drawingModeEnabled;
}

public Point2D toModelCoords(Point2D p) {
    try {
        return transform.inverseTransform(p, null);
    } catch (NoninvertibleTransformException e) {
        e.printStackTrace();
    }
    return null;
}

Thanks for the help!

SIGC
  • 11
  • 2

0 Answers0