2010-10-31 22 views
2

我的監控是在paintComponent()方法中使用2D圖形繪製多個圖像。但是,我不確定如何添加MouseListener,以便每個圖像都知道它是否被選中。圖像映射像Java swing中的功能,點vs GeneralPath

我到目前爲止的解決方案太簡單地記錄鼠標點擊的座標,看看它們是否包含在每個圖像的邊界內。但是,對於具有更復雜邊界的圖像來說,這將很困難。

另一種選擇是創建簡單的形狀並將它們放置在圖像上,但是具有更復雜邊界的圖像將很困難。在關於SO的另一個討論中發現了 here,有人提到使用GeneralPath繪製更復雜的形狀。我從來沒有玩過,但這似乎令人鼓舞。

這兩個選項中,似乎是最好的解決辦法,還是有其他的建議

回答

2

你畫在彼此頂部圖像或者他們單獨繪製。

如果它們分開繪製,那麼您應該在JComponent上進行自定義繪製。然後你可以使用GeneralPath來完成繪圖。您還需要通過檢查GeneralPath中是否包含鼠標單擊來實現contains(...)方法。如果contains()方法正確實現,那麼MouseListener將正確響應。

下面是一個簡單的例子:

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

public class RoundButton extends JButton { 
    public RoundButton(String label) { 
     super(label); 

     // These statements enlarge the button so that it 
     // becomes a circle rather than an oval. 
     Dimension size = getPreferredSize(); 
     size.width = size.height = Math.max(size.width, size.height); 
     setPreferredSize(size); 

     // This call causes the JButton not to paint the background. 
     // This allows us to paint a round background. 
     setContentAreaFilled(false); 
    } 

    // Paint the round background and label. 
    protected void paintComponent(Graphics g) { 
    if (getModel().isArmed()) { 
      // You might want to make the highlight color 
      // a property of the RoundButton class. 
      g.setColor(Color.lightGray); 
     } else { 
      g.setColor(getBackground()); 
     } 
    g.fillOval(0, 0, getSize().width-1, getSize().height-1); 

     // This call will paint the label and the focus rectangle. 
    super.paintComponent(g); 
    } 

    // Paint the border of the button using a simple stroke. 
    protected void paintBorder(Graphics g) { 
     g.setColor(getForeground()); 
     g.drawOval(0, 0, getSize().width-1, getSize().height-1); 
    } 

    // Hit detection. 
    Shape shape; 
    public boolean contains(int x, int y) { 
     // If the button has changed size, make a new shape object. 
     if (shape == null || !shape.getBounds().equals(getBounds())) { 
      shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight()); 
     } 
     return shape.contains(x, y); 
    } 

    // Test routine. 
    public static void main(String[] args) { 
     // Create a button with the label "Jackpot". 
     JButton button = new RoundButton("Jackpot"); 
     button.setBackground(Color.green); 
     button.setBounds(0, 0, 100, 100); 

     JButton button2 = new RoundButton("Jackpot2"); 
     button2.setBackground(Color.red); 
     button2.setBounds(50, 50, 100, 100); 

     // Create a frame in which to show the button. 
     JFrame frame = new JFrame(); 
     frame.getContentPane().setBackground(Color.yellow); 
     frame.getContentPane().setLayout(null); 
     frame.getContentPane().add(button); 
     frame.getContentPane().add(button2); 
//  frame.getContentPane().setLayout(new FlowLayout()); 
     frame.setSize(200, 200); 
     frame.setVisible(true); 

     MouseListener mouseListener = new MouseAdapter() { 
      public void mouseEntered(MouseEvent e) 
      {} 

      public void mouseExited(MouseEvent e) 
      {} 

      public void mouseClicked(MouseEvent e) 
      { 
       System.out.println("clicked "); 
      } 

      public void mousePressed(MouseEvent e) 
      { 
       System.out.println("pressed "); 
      } 

      public void mouseReleased(MouseEvent e) 
      { 
       System.out.println("released "); 
      } 
     }; 
     button.addMouseListener(mouseListener); 

    } 
} 
+0

這看起來像它應該工作。關於您是否將圖像繪製在彼此之上的問題......我希望在一個paintComponent()方法中繪製大約7-8張圖像。這將需要7-8個contains()方法。難道我不能單獨擁有各自具有自己形狀的類來實現此目的,而不是將圖像本身分開嗎?謝謝。 – Koop 2010-10-31 04:22:34

+0

你應該有獨立的組件,這樣每個組件都可以有自己的形狀。然後,只需將這些「形狀組件」添加到面板中,就如同使用其他任何Swing組件一樣。如果組件不分層,處理起來會更容易。但是,組件可以分層,但請記住,根據組件的ZOrder,只有頂部的組件纔會收到鼠標事件。 – camickr 2010-10-31 15:25:35