2012-11-22 34 views

回答

1

你有多种选择......

  1. 使用地图图像来定义图像的可点击的位置。这将需要第二张图像的大小与第一张图像的大小相同,以便在运行时识别可以点击或不显示的区域。
  2. 定义一系列代表可点击位置的“形状”。这些可以被命名并保存到一个文件中,从而可以独立于代码定义这些区域。

以下示例使用两者;

“主” 图像

enter image description here

“地图” 图像

enter image description here

public class TestImageMap { 

    private BufferedImage master; 
    private BufferedImage masterMap; 

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

    public TestImageMap() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       try { 

        master = ImageIO.read(getClass().getResource("/Master.png")); 
        masterMap = ImageIO.read(getClass().getResource("/MasterMap.png")); 

        JFrame frame = new JFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setLayout(new GridLayout(2, 1)); 
        frame.add(new MapPane()); 
        frame.add(new CoordPane()); 
        frame.pack(); 
        frame.setLocationRelativeTo(null); 
        frame.setVisible(true); 

       } catch (Exception exp) { 
        exp.printStackTrace(); 
        System.exit(0); 
       } 
      } 
     }); 
    } 

    public void sendMoney() { 
     JOptionPane.showMessageDialog(null, "Sending money :D"); 
    } 

    public void sendMoreMoney() { 
     JOptionPane.showMessageDialog(null, "Sending ALL your money 8D"); 
    } 

    public abstract class AbstractImagePane extends JPanel { 

     public AbstractImagePane() { 

      MouseAdapter handler = new MouseAdapter() { 
       @Override 
       public void mouseClicked(MouseEvent e) { 
        doMouseClicked(e); 
       } 

       @Override 
       public void mouseMoved(MouseEvent e) { 
        doMouseMoved(e); 
       } 
      }; 

      addMouseMotionListener(handler); 
      addMouseListener(handler); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(), master.getHeight()); 
     } 

     protected void doMouseClicked(MouseEvent evt) { 
      if (evt.getButton() == MouseEvent.BUTTON1) { 
       if (evt.getClickCount() == 1) { 
        Point p = evt.getPoint(); 
        if (containsMoney(p)) { 
         sendMoney(); 
        } else if (containsMoreMoney(p)) { 
         sendMoreMoney(); 
        } 
       } 
      } 
     } 

     protected void doMouseMoved(MouseEvent evt) { 
      Cursor cursor = Cursor.getDefaultCursor(); 
      Point p = evt.getPoint(); 
      if (containsMoney(p) || containsMoreMoney(p)) { 
       cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); 
      } 
      setCursor(cursor); 
     } 

     protected abstract boolean containsMoney(Point p); 
     protected abstract boolean containsMoreMoney(Point p); 

     protected Point normalize(Point p) { 
      Point offset = getImageOffset(); 
      Point norm = new Point(); 
      norm.x = p.x - offset.x; 
      norm.y = p.y - offset.y; 
      return norm; 
     } 

     protected Point getImageOffset() { 
      int width = getWidth() - 1; 
      int height = getHeight() - 1; 
      int x = (width - master.getWidth())/2; 
      int y = (height - master.getHeight())/2; 

      return new Point(x, y); 

     } 

     @Override 
     public void paint(Graphics g) { 
      super.paint(g); 
      if (master != null) { 
       Point offset = getImageOffset(); 
       g.drawImage(master, offset.x, offset.y, this); 
      } 
     } 
    } 

    public class MapPane extends AbstractImagePane { 

     private Rectangle moneyBounds = new Rectangle(16, 24, 139, 36); 
     private Rectangle moreMoneyBounds = new Rectangle(16, 70, 139, 34); 

     @Override 
     protected boolean containsMoney(Point p) { 
      return moneyBounds.contains(normalize(p)); 
     } 

     @Override 
     protected boolean containsMoreMoney(Point p) { 
      return moreMoneyBounds.contains(normalize(p)); 
     } 
    } 

    public class CoordPane extends AbstractImagePane { 

     protected boolean contains(Point p, int rgb) { 
      Point norm = normalize(p); 
      return masterMap.getRGB(norm.x, norm.y) == rgb; 
     } 

     @Override 
     protected boolean containsMoney(Point p) { 
      int white = new Color(255, 255, 255).getRGB(); 
      return contains(p, white); 
     } 

     @Override 
     protected boolean containsMoreMoney(Point p) { 
      int red = new Color(255, 0, 0).getRGB(); 
      return contains(p, red); 
     } 
    } 
} 
+0

首先,感谢您花费大量精力编写所有这些内容。不幸的是,代码对我来说太过分了。任何帮助理解它将不胜感激。你的代码不仅仅是建立一个可点击区域吗?任何方式将其归结为像确定像素位置,绘制框,使框可点击特定超链接等简单的东西?谢谢。 –