Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
274 views
in Technique[技术] by (71.8m points)

java - Get mouse detection with a dynamic shape

Basically I'm constructing a world map. I know how to have a square click area. But I'd like to make it so I can put the countries together and be able to click on the country. Now it's pretty obvious that I can't use square click areas for that because I'd have overlapping click areas. Could I do it by looking at the transparency of each pixel? Even so I don't know how to do that?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Use Shape.contains(Point2D) - something like this:

Shape Containment

This example uses overlapping ellipses to show how the contains(..) method will accurately identify which ovals the mouse click falls inside. But the kind of map you are referring to will probably be made of a number of GeneralPath objects (one for each country) that do not overlap.

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.BasicStroke;
import java.awt.RenderingHints;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import java.io.File;
import java.util.*;
import javax.imageio.ImageIO;

public class ShapeContainment {

    List<Ellipse2D> shapes = new ArrayList<Ellipse2D>();
    int w = 400;
    int h = 100;
    BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
    Point2D mouse = new Point2D.Double(0, 0);
    JLabel l;

    ShapeContainment() {
        Random r = new Random();
        for (int ii = 0; ii < 10; ii++) {
            int x = r.nextInt(w / 2);
            int y = r.nextInt(h / 2);
            int wE = r.nextInt(w - x);
            int hE = r.nextInt(h - y);
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, wE, hE);
            shapes.add(ellipse);
        }
        l = new JLabel(new ImageIcon(img));
        MouseAdapter listener = new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent me) {
                mouse = me.getPoint();
                drawImage();
            }
        };
        l.addMouseListener(listener);
        drawImage();

        JOptionPane.showMessageDialog(null, l);
    }

    public void drawImage() {
        Graphics2D g = img.createGraphics();
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, w, h);

        RenderingHints hints = new RenderingHints(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHints(hints);

        Color bg = new Color(0, 128, 0, 60);
        Color inside = new Color(0, 0, 255, 120);
        Color outside = new Color(255, 0, 0, 120);
        g.setStroke(new BasicStroke(4));
        for (Ellipse2D shape : shapes) {
            g.setColor(bg);
            g.fill(shape);
            if (shape.contains(mouse)) {
                g.setColor(inside);
            } else {
                g.setColor(outside);
            }
            g.draw(shape);
        }
        g.setColor(Color.RED);
        int x = (int) mouse.getX();
        int y = (int) mouse.getY();
        g.setStroke(new BasicStroke(2));
        int s = 3;
        g.drawLine(x-s, y, x+s, y);
        g.drawLine(x, y-s, x, y+s);
        l.setIcon(new ImageIcon(img));

        g.dispose();

        try {
            ImageIO.write(
                    img,
                    "png",
                    new File(System.currentTimeMillis() + ".png"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Runnable run = new Runnable() {

            @Override
            public void run() {
                new ShapeContainment();
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(run);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...