如何在Java swing中构建点击组件?
我构建了一个仅显示一行的自定义组件。该线是在 Paint 方法中作为 Line2D 从左上角绘制到右下角的。背景是透明的。我扩展了 JComponent。这些线条组件是可拖动的,并在鼠标指针位于最大位置时更改其线条颜色。距绘制线 15 个像素。 但是,如果我将多个这些组件添加到扩展 JPanel 的另一个自定义组件中,它们有时会重叠。我想实现的是,如果鼠标指针距离该线超过 15 个像素,则鼠标事件应该穿过该组件。如何让它落空是我的问题。 这可能吗?
提前致谢!
I have built a custom component that shows only a line. The line is drawn from the top left corner to the bottom right corner as a Line2D at the paint method. The background is transparent. I extended JComponent. These line components are draggable and change their line color when the mouse pointer is located max. 15 pixels away from the drawn line.
But if I have multiple of these components added to another custom component that extends JPanel they sometimes overlap. I want to implement that if the mouse pointer is more than 15 pixels away from the line the mouse events should fall through the component. How to let it fall through is my problem.
Is that even possible?
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您的子组件有鼠标侦听器,那么它将拦截其上发生的每个鼠标事件。如果您想将 MouseEvent 转发到父组件,您应该手动执行此操作。例如,您可以实现扩展 MouseAdapter 的自定义鼠标侦听器:
If your child component has a mouse listener, then it will intercept every mouse event occurring over it. If you want to forward the MouseEvent to the parent Component you should manually do it. For example you can implement your custom mouse listener extending MouseAdapter:
在大学最后一年的项目中,我做了一个白板程序并遇到了同样的问题。对于用户在板上绘制的每个形状,我创建了一个 JComponent,这在绘制矩形时很好,但使用自由形状线条工具会更困难。
我最终解决这个问题的方法是完全取消 JComponent。我有一个 JPanel,其中包含一个自定义 Shape 对象的 Vector(我认为)。每个对象都有自己的坐标和线条粗细等。当用户单击面板时,JPanel 上的鼠标侦听器会触发并遍历每个 Shape,对每个 Shape 调用 contains(int x, int y) 方法(x 和 y 是事件的坐标)。因为形状是在绘制时添加到向量中的,所以我知道最后一个返回 true 的是最上面的形状。
这就是我用于直线包含方法的方法。数学可能有点不确定,但它对我有用。
posX 和 posY 构成了线的起点坐标,endX 和 endY 是线的终点。如果单击位于线中心的 lineThickness/2 范围内,则返回 true,否则您必须沿着线的中间向右单击。
绘制形状是将 JPanel 的 Graphics 对象传递给每个形状并用它进行绘制的情况。
For my final year project at university I did a whiteboard program and had the same problem. For each shape the user drew on the board I created a JComponent, which was fine when they were drawing rectangles, but more difficult with the free form line tool.
The way I fixed it in the end was to do away with JComponents altogether. I had a JPanel which held a Vector (I think) of custom Shape objects. Each object held its own coordinates and line thicknesses and such. When the user clicked on the board, the mouse listener on the JPanel fired and went through each Shape calling a contains(int x, int y) method on each one (x and y being the coordinates of the event). Because the Shapes were added to the Vector as they were drawn I knew that the last one to return true was the topmost Shape.
This is what I used for a straight line contains method. The maths might be a bit iffy but it worked for me.
posX and posY make up the coordinates of the start of the line and endX and endY are, yep, the end of the line. This returned true if the click is within lineThickness/2 of the centre of the line, otherwise you have to click right along the very middle of the line.
Drawing the Shapes was a case of passing in the JPanel's Graphics object to each Shape and doing the drawing with that.
自从我接触 Swing 以来已经有一段时间了,但我认为您需要在父组件中处理鼠标事件,然后用行循环遍历子组件并确定其中哪个应该处理该事件(好吧,决定的逻辑应仍保留在行组件中,但父组件将显式调用该逻辑,直到组件之一获取事件)。
It's been a while since I touched Swing, but I think you will need to handle your mouse events in the parent component and then loop through the child components with lines and determine which one of them should handle the event (well, the logic of deciding should still remain in the line component, but parent will explicitly invoke that logic until one of the components takes the event).
我相信最简单的方法是捕获事件并调用parent.processEvent()。因此,您的组件对于事件来说是透明的,因为它将它们传播到父级。
I believe that the easiest way is to catch the event and call
parent.processEvent()
. So, you component will be transparent for events because it will propagate them to parent.我一直在努力解决这类问题,并尝试了与父母和 glasspane 一起使用的所有方法,直到我意识到覆盖
contains
方法正是您想要的。因为当父级触发某种getcomponent
时,您的“Line”会回复它:“不,不是我,我不在那里!”并且循环将检查其他组件。另外,当您需要为可拖动对象设置复杂的深度时,您可以使用 JLayeredPane 后代。
I was struggling with this sort of question and tried all the stuff with parents and glasspane until i realised that override of
contains
method does just what you want. Because when parent fires some sort ofgetcomponent
your 'Line' will reply to it: 'no, its not me, i'm not there!' and the loop will check other components.Also, when you need to setup a complex depth to your draggable object, you can use JLayeredPane descendant.