当我运行您发布的代码时,我收到了NullPointerException 。 这是堆栈跟踪的一部分。 (请注意,我的环境是[64位] Windows 10上的JDK 13.0.1。)
Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: contentPane cannot be set to null.
at java.desktop/javax.swing.JRootPane.setContentPane(JRootPane.java:598)
at java.desktop/javax.swing.JFrame.setContentPane(JFrame.java:679)
at generalp/guitests.mouse_input.displayJframe(mouse_input.java:27)
您发布的这一行代码导致了错误。
frame.setContentPane(new mouse_input().mouse_pad);
这是因为mouse_pad从未初始化。
这很容易解决。
private JPanel mouse_pad = new JPanel();
当我运行更改的代码时,将显示以下窗口。
这是因为JPanel与所有Swing容器一样,没有定义的大小,因为它采用了其包含的[GUI]组件的大小。 实际上,方法pack()将JFrame大小调整为足以容纳所有包含的组件的大小,并且唯一包含的组件是大小为零的JPanel 。 因此,对于您发布的代码,为了拥有合适的尺寸窗口,我们需要显式设置尺寸。 所以我们需要(例如)而不是pack() )
frame.setSize(400, 300);
现在,当我运行更新的代码时,我得到
label在哪里? 根据您发布的代码,它永远不会添加到frame 。 您要向frame添加两个组件,即mouse_pad和label 。 如果将mouse_pad设置为“内容窗格”,那么您将无处可去,无法添加label 。 这是布局管理器变得重要的地方。 不幸的是,如果您不熟悉Swing并且依赖GUI构建器,那么如何利用布局管理器来组织您希望显示的所有组件并不是很明显。 我认为学习基础知识很重要。 GUI构建器适用于熟悉Swing并且知道如何利用该构建器节省时间和精力的程序员。 它不是学习Swing或缩短学习曲线的工具。 因此,作为了解基础知识的人,我知道内容窗格的默认布局管理器是BorderLayout ,因此在您发布的代码中,我现在将对setContentPane()方法的调用替换为以下内容。
frame.add(mouse_pad, BorderLayout.CENTER);
createUIComponents(); // in order to initialize member 'label'
frame.add(label, BorderLayout.PAGE_START);
最后,您需要向接收鼠标运动事件的组件添加MouseMotionListener 。 这不是JFrame而是JPanel ,在这种情况下为mouse_pad 。 此外,GUI构建器可能不会让你知道类MouseMotionAdapter它实现MouseMotionListener与空的方法,因此,如果你写一个类,它扩展MouseMotionAdapter你只需要执行相关的方法,而不是所有的方法,这说明你在注意什么在您发布的代码中进行以下注释。
// It doesn't like me deleting this
这是固定代码。 这不是最好的实现,但它回答了您的问题,基本上是:
我的代码不起作用。 我应该如何更改才能使其正常工作?
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseInput {
private JPanel mouse_pad = new JPanel();
private JLabel label;
private static int x;
private static int y;
public static void main(String[] args) {
MouseInput instance = new MouseInput();
SwingUtilities.invokeLater(new Runnable(){
public void run(){
instance.createUIComponents();
instance.displayJframe();
}
});
}
public void displayJframe(){
// Create blank content frame
JFrame frame = new JFrame("Mouse Input");
frame.add(mouse_pad, BorderLayout.CENTER);
frame.add(label, BorderLayout.PAGE_START);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setVisible(true);
// Add mouse motion listener
mouse_pad.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
x = e.getX();
y = e.getY();
label.setText("X = " + x + " , Y = " + y);
}
});
// Set cursor type
frame.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
// Display frame
frame.setVisible(true);
}
private void createUIComponents() {
label = new JLabel();
label.setText("X = " + x + " , Y = " + y);
}
}
但是,如果您只是开始使用Java进行GUI编程,那么您是否考虑过JavaFX ,它打算作为Swing的更现代的替代品。