我知道这个问题早就被问过了,但是我会创建一个JComponent,将其呈现为该按钮,然后检查点击了图像的哪个部分。就像这样:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
public class FivePartCircleButton extends JComponent implements SwingConstants
{
private static final float PERCENT_PADDING_MIDDLE = 0.1571428571428571f;
private static final float PERCENT_PADDING_EDGE = 0.0535714285714286f;
private static Image button;
private List<ActionListener> topListeners = new LinkedList<ActionListener>();
private List<ActionListener> rightListeners = new LinkedList<ActionListener>();
private List<ActionListener> bottomListeners = new LinkedList<ActionListener>();
private List<ActionListener> leftListeners = new LinkedList<ActionListener>();
private List<ActionListener> middleListeners = new LinkedList<ActionListener>();
private String actionCommand;
public FivePartCircleButton()
{
try
{
if (button == null)
button = Toolkit.getDefaultToolkit().createImage(new URL("http://mygimptutorial.com/preview/round-web20-button-with-metal-ring.jpg"));
}
catch (MalformedURLException e) {e.printStackTrace();}
this.setPreferredSize(new Dimension(280, 280));
this.addMouseListener(mouseAdapter);
}
private MouseAdapter mouseAdapter = new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
Ellipse2D innerCircle = getShapeOfOval(PERCENT_PADDING_MIDDLE);
Ellipse2D outerCircle = getShapeOfOval(PERCENT_PADDING_EDGE);
if (innerCircle.contains(e.getPoint()))
processClick(middleListeners);
else if (outerCircle.contains(e.getPoint()))
{
float lineFromTopLeftToBottomRight = e.getY() * ((float)getWidth() / (float)getHeight());
float lineFromTopRightToBottomLeft = getWidth() - lineFromTopLeftToBottomRight;
if (e.getX() < lineFromTopLeftToBottomRight)
{
if (e.getX() < lineFromTopRightToBottomLeft)
processClick(leftListeners);
else
processClick(bottomListeners);
}
else
{
if (e.getX() < lineFromTopRightToBottomLeft)
processClick(topListeners);
else
processClick(rightListeners);
}
}
}
};
private void processClick(List<ActionListener> listeners)
{
for (ActionListener l : listeners)
l.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, actionCommand));
}
public void addActionListener(ActionListener listener, int side)
{
switch (side)
{
case TOP:
topListeners.add(listener);
break;
case RIGHT:
rightListeners.add(listener);
break;
case BOTTOM:
bottomListeners.add(listener);
break;
case LEFT:
leftListeners.add(listener);
break;
case CENTER:
middleListeners.add(listener);
break;
}
}
private Ellipse2D getShapeOfOval(float percentPadding)
{
float x = getWidth() * percentPadding;
float y = getHeight() * percentPadding;
float w = getWidth() - x - x;
float h = getHeight() - y - y;
Ellipse2D circle = new Ellipse2D.Float(x, y, w, h);
return circle;
}
@Override
protected void paintComponent(Graphics g)
{
g.drawImage(button, 0, 0, this.getWidth(), this.getHeight(), this);
}
public void setActionCommand(String actionCommand)
{
this.actionCommand = actionCommand;
}
}
简而言之,按钮会呈现为您链接的图像。然后,当您单击图像时,它会检查您单击了图像的哪个部分。这是通过创建两个与您图像上的椭圆匹配的椭圆来完成的。如果您单击的点在较小的椭圆内,则通知中间的ActionListeners。如果不在其中,但在较大的椭圆内,则我们知道单击在环上。然后,我们检查单击的椭圆的哪一侧,并通知相应的操作侦听器。
另外,请注意:
PERCENT_PADDING_MIDDLE
和
PERCENT_PADDING_EDGE
是特定于您链接的图像的,并假定图像周围有相等的填充。这是通过将图像上的填充像素数除以图像宽度来确定的。