我尝试将Polygon
扩展为我选择的数据类(实现MouseListener
)。父paintComponent
中的JPanel
覆盖正在使用Polygon
呈现扩展的Hexagon
类(我称之为.fillPolygon
) - 它渲染得很好!
但它不允许我与代码中实现的MouseListener
进行交互。是否有某个阶段我在某个地方失踪?
寻找灵感,来到这里:
https://docs.oracle.com/javase/tutorial/2d/advanced/user.html
不幸的是,这限制了应用程序 - 它可以很好地处理事件点击,但是对于使用悬停事件,应用于父容器的MouseListener
意味着它只跟踪进入/退出该容器。在该容器内的Shape
进入/退出时无法使其正常工作。
Hexagon
(抽象类):
import java.awt.Polygon;
import java.util.ArrayList;
import spare.Theme;
public abstract class Hexagon extends Polygon {
private static final long serialVersionUID = 1L;
public enum HEX_TYPE { ALIVE, INFECTED, DEAD };
public enum SELECTION_TYPE { SELECTED, GROUPED, NONE };
private int hexEdgeWidth = 20;
private int hexBorderWidth = 3;
private ArrayList<Hexagon> children;
private Theme theme;
private boolean hover = false;
private boolean selected = false;
public ArrayList<Hexagon> getChildren() {
return children;
}
public int getHexEdgeWidth() {
return hexEdgeWidth;
}
public void setHexEdgeWidth(int hexEdgeWidth) {
this.hexEdgeWidth = hexEdgeWidth;
}
public int getHexBorderWidth() {
return hexBorderWidth;
}
public void setHexBorderWidth(int hexBorderWidth) {
this.hexBorderWidth = hexBorderWidth;
}
public void setChildren(ArrayList<Hexagon> children) {
this.children = children;
}
public Theme getTheme() {
return theme;
}
public void setTheme(Theme theme) {
this.theme = theme;
}
public boolean isHover() {
return hover;
}
public void setHover(boolean hover) {
this.hover = hover;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
BasicHexagon
(具体子类):
import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import spare.Theme;
public class BasicHexagon extends Hexagon implements MouseListener {
private static final long serialVersionUID = 1L;
public BasicHexagon() {
setChildren(null);
int n = 6;
int size = getHexEdgeWidth();
for (int i = 0; i < n; i++) {
// x + radius * cosine of angle * iteration in radians
// y + radius * sine of angle * iteration in radians
addPoint(
(int) (size * Math.cos(Math.toRadians(360 / n * i))),
(int) (size * Math.sin(Math.toRadians(360 / n * i))));
}
setTheme(new Theme(
new Color(255, 255, 255, 180), // primary
new Color(255, 255, 255, 255), // primary hover
new Color(255, 0, 0, 180), // secondary
new Color(255, 0, 0, 255), // secondary hover
new Color(255, 255, 100, 255), // border
new Color(255, 255, 100, 255))); // text
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
BasicHexagon bH = (BasicHexagon) e.getSource();
if(bH.isSelected()) {
bH.setSelected(false);
} else {
bH.setSelected(true);
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
BasicHexagon bH = (BasicHexagon) e.getSource();
bH.setHover(true);
System.out.println("in the zone");
}
@Override
public void mouseExited(MouseEvent e) {
BasicHexagon bH = (BasicHexagon) e.getSource();
bH.setHover(false);
System.out.println("fleeing");
}
}
paintComponent
我的自定义JPanel
:
@Override
public void paintComponent(Graphics g) {
Toolkit.getDefaultToolkit().sync();
super.paintComponent(g);
switch (getGameState()) {
case IN_GAME:
doIngameDrawing(g);
break;
case END_GAME:
break;
case PAUSED:
break;
case PRE_GAME:
break;
default:
break;
}
}
private void doIngameDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for(Hexagon h : getTiles()) {
h.translate(getPreferredSize().width / 2, getPreferredSize().height / 2);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if(h.isHover() && h.isSelected()) {
g2d.setColor(h.getTheme().getSecondaryHover());
g2d.fillPolygon(h);
} else if(h.isHover()) {
g2d.setColor(h.getTheme().getPrimaryHover());
g2d.fillPolygon(h);
} else if(h.isSelected()) {
g2d.setColor(h.getTheme().getSecondary());
g2d.fillPolygon(h);
} else {
// draw the normal colours;
g2d.setColor(h.getTheme().getPrimary());
g2d.fillPolygon(h);
}
g2d.setStroke(new BasicStroke(h.getHexBorderWidth()));
g2d.setColor(h.getTheme().getBorder());
g2d.drawPolygon(h);
if(h.getChildren() != null) {
// child rendering goes here
}
}
g2d.dispose();
}
答案 0 :(得分:1)
您必须使用mouseMoved()
。然后,您可以检查鼠标光标下当前的形状并做出相应的反应。你可以这样做:
// This is in your custom JPanel, which for simplicity is also its own MouseListener.
// Assuming getHexagons() returns Hexagon[].
// Assuming Hexagon implements MouseListener.
private Hexagon lastHovered;
public void mouseMoved(MouseEvent e) {
Hexagon current = null;
boolean changed = false;
for (Hexagon hex : getHexagons()) {
if (hex.contains(e.getX(), e.getY())) {
current = hex;
break;
}
}
if (lastHovered != current) {
changed = true;
if (lastHovered != null) {
lastHovered.mouseExited(e);
}
if (current != null) {
current.mouseEntered(e);
}
}
lastHovered = current;
if (changed) {
repaint();
}
}
由于contains()
是Shape
的方法,因此适用于任何形状。由于您的形状实现了MouseListener
,因此您可以实现输入/退出功能并将鼠标事件传递给它们。