我要做的是:绘制一条垂直线和一条水平线,它们彼此垂直并且与鼠标指向的位置相交。一种光标跟踪器。
我的结构:JFrame - > CustomPanel - >其他面板/组件等。
CustomPanel继承自JPanel,并将其设置为我的JFrame的ContentPane。
我尝试使用GlassPane,一切都很完美,但我想保留我的事件,而不是禁用它们。我仍然希望能够点击按钮等。
相关问题是Painting over the top of components in Swing?。当我将鼠标移动到CustomPanel中有空位的地方时,一切都按预期运行,但它仍然不会覆盖其他组件。
在图像中它应该继续画在按钮上,但是当我进入它时它停止了,然后在我退出时恢复。
以下代码。
public class Painter {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
JFrame frame = new JFrame();
frame.setSize(600, 600);
frame.setPreferredSize(new Dimension(600, 600));
frame.setContentPane(new CustomPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
class CustomPanel extends JPanel {
int x = 0;
int y = 0;
public CustomPanel() {
addMouseListener(new AdapterImplementation(this));
addMouseMotionListener(new AdapterImplementation(this));
add(new JButton("TESTBTN"));
setSize(new Dimension(600, 600));
setPreferredSize(new Dimension(600, 600));
setVisible(true);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawLine(0, y, getWidth(), y);
g.drawLine(x, 0, x, getHeight());
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
和我的适配器:
public class AdapterImplementation extends MouseAdapter {
CustomPanel pane;
public AdapterImplementation(CustomPanel pane) {
this.pane = pane;
}
@Override
public void mouseDragged(MouseEvent e) {
int x = e.getX();
int y = e.getY();
pane.setX(x);
pane.setY(y);
pane.repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
System.out.println("MOUSE MOVED");
int x = e.getX();
int y = e.getY();
pane.setX(x);
pane.setY(y);
pane.repaint();
}
}
答案 0 :(得分:2)
此处的问题是MouseListeners
已在您的CustomPanel
注册,但未在JButton
注册,因此后者不会处理来自听众的事件。
此外,正如您所见,使用GlassPane时将阻止对基础组件的事件。
可以使用JLayeredPane
作为最顶层的容器来使用当前的侦听器捕获MouseEvents
。
注意:在Swing中覆盖paintComponent
代替paint
进行自定义绘制,并记得调用super.paintComponent(g)
。