如何从 Mouseevents 中隐藏 JComponent 的一部分?例如。 JButton 的某些区域没有反应,休息很好
How can part of JComponent be obscured from Mouseevents? E.g. some region of JButton not reacting, rest is fine
这个问题花了我很多时间来确定,现在我很好奇是什么导致了这种奇怪的行为:
在示例中,有一个 JFrame class,它显示一个 JPanel“页面”,它本身获取对“父”JFrame 的引用。
我的错误是在构建对象的过程中这样做了。
令人惊叹的是,在某些情况下,JComponents 在“页面”上的反应(如 JButtons、JRadioButtons、JCHeckboxes 等),有时对鼠标的反应很好,有时则完全没有,并且有时只有一小部分表面在工作。
所以我尝试在下面的最小示例中将其隔离,我可以在 Windows 7 x64 和 Windows 10 x64 上的 JRE 1.8、JRE12 和 JRE13 上进行演示。
为了重现,您可能需要调整按钮大小与 JFrame.setSize()
。
在我的系统上,按钮对鼠标的反应非常好,mouseEntered
上有一些动画,用鼠标单击会触发 ActionEvent
。
但不在按钮右下角的固定大小区域。如果你用鼠标去那里,不会触发任何事件。
在 windows 大小和组件大小的变化下,该“死”区域的大小保持不变,因为您可以在“页面”代码中尝试使用不同的 LayoutManagers
。
这同样适用于触发事件的其他 JComponents。
我的问题是:为什么ActionListening-System有问题。如果 Listening 要么完全被破坏,要么根本没有,这将是直观的。
希望从回答中了解更多关于JComponents中鼠标事件生成的内幕,以便在以后的程序中更加警惕。
这是主要的 JFFrame:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TESTFRAME extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TESTFRAME();
}
});
}
public TESTFRAME() {
super("TESTFRAME");
PAGE page = new PAGE();
/*
* the following line causes very strange behaviour!
*/
page.setParent(this);
JPanel DISPLAY = new JPanel(new BorderLayout());
DISPLAY.add(page);
add(DISPLAY);
setSize(800, 600);
setLocationByPlatform(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
}
仅供参考,还检查注释掉行 page.setParent(this);
.
时会发生什么
这是要在框架中显示的“页面”:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PAGE extends JPanel implements ActionListener {
public TESTFRAME parent = null;
public PAGE() {
// !!! activate the following line setting the GridLayout, to make button large
// in the bottom right corners, I continue not being able to click
// setLayout(new GridLayout(1, 0));
JButton bt_large = new JButton("<html><br>large close button<br><br></html>");
bt_large.addActionListener(this);
add(bt_large);
JButton bt_small = new JButton("small button");
bt_small.addActionListener(this);
add(bt_small);
}
public TESTFRAME getParent() {
return parent;
}
public void setParent(TESTFRAME parent) {
this.parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("button click received!");
if (parent != null) {
parent.dispose();
}
}
}
感谢您的见解!
问题是getParent()
是Component
class的一个方法。
通过实施您自己的方法,默认功能会丢失,从而导致您遇到问题。
尝试将您的方法重命名为 getParentFrame()
和 setParentFrame()
以查看正常行为。
但是,您甚至不需要那些方法。相反,您可以使用 JDK.
中的方法访问面板的父框架
在您的 ActionListener
中,您可以使用如下代码:
Window window = SwingUtilities.windowForComponent( this );
window.dispose();
这个问题花了我很多时间来确定,现在我很好奇是什么导致了这种奇怪的行为:
在示例中,有一个 JFrame class,它显示一个 JPanel“页面”,它本身获取对“父”JFrame 的引用。 我的错误是在构建对象的过程中这样做了。
令人惊叹的是,在某些情况下,JComponents 在“页面”上的反应(如 JButtons、JRadioButtons、JCHeckboxes 等),有时对鼠标的反应很好,有时则完全没有,并且有时只有一小部分表面在工作。
所以我尝试在下面的最小示例中将其隔离,我可以在 Windows 7 x64 和 Windows 10 x64 上的 JRE 1.8、JRE12 和 JRE13 上进行演示。
为了重现,您可能需要调整按钮大小与 JFrame.setSize()
。
在我的系统上,按钮对鼠标的反应非常好,mouseEntered
上有一些动画,用鼠标单击会触发 ActionEvent
。
但不在按钮右下角的固定大小区域。如果你用鼠标去那里,不会触发任何事件。
在 windows 大小和组件大小的变化下,该“死”区域的大小保持不变,因为您可以在“页面”代码中尝试使用不同的 LayoutManagers
。
这同样适用于触发事件的其他 JComponents。
我的问题是:为什么ActionListening-System有问题。如果 Listening 要么完全被破坏,要么根本没有,这将是直观的。
希望从回答中了解更多关于JComponents中鼠标事件生成的内幕,以便在以后的程序中更加警惕。
这是主要的 JFFrame:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TESTFRAME extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TESTFRAME();
}
});
}
public TESTFRAME() {
super("TESTFRAME");
PAGE page = new PAGE();
/*
* the following line causes very strange behaviour!
*/
page.setParent(this);
JPanel DISPLAY = new JPanel(new BorderLayout());
DISPLAY.add(page);
add(DISPLAY);
setSize(800, 600);
setLocationByPlatform(true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
}
仅供参考,还检查注释掉行 page.setParent(this);
.
这是要在框架中显示的“页面”:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class PAGE extends JPanel implements ActionListener {
public TESTFRAME parent = null;
public PAGE() {
// !!! activate the following line setting the GridLayout, to make button large
// in the bottom right corners, I continue not being able to click
// setLayout(new GridLayout(1, 0));
JButton bt_large = new JButton("<html><br>large close button<br><br></html>");
bt_large.addActionListener(this);
add(bt_large);
JButton bt_small = new JButton("small button");
bt_small.addActionListener(this);
add(bt_small);
}
public TESTFRAME getParent() {
return parent;
}
public void setParent(TESTFRAME parent) {
this.parent = parent;
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("button click received!");
if (parent != null) {
parent.dispose();
}
}
}
感谢您的见解!
问题是getParent()
是Component
class的一个方法。
通过实施您自己的方法,默认功能会丢失,从而导致您遇到问题。
尝试将您的方法重命名为 getParentFrame()
和 setParentFrame()
以查看正常行为。
但是,您甚至不需要那些方法。相反,您可以使用 JDK.
中的方法访问面板的父框架在您的 ActionListener
中,您可以使用如下代码:
Window window = SwingUtilities.windowForComponent( this );
window.dispose();