使用 ActionListener 按钮单击以隐藏一个 JFrame 并显示另一个时出错
Error when using ActionListener button click to hide a JFrame and reveal another
我正在尝试在单击按钮(在本例中为尺寸按钮)时“打开”另一个 JFrame window,就像浏览菜单时一样。我的 2 windows、Main 函数和 ActionListener 是分开的 类。当我单击应该将我重定向到另一个 window 的按钮时,它只是显示一个错误,并没有隐藏第一个 window 并显示第二个。错误是:
"Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class javax.swing.JButton cannot be cast to class javax.swing.JFrame (javax.swing.JButton and javax.swing.JFrame are in module java.desktop of loader 'bootstrap')
at ActionDimensions.actionPerformed(ActionDimensions.java:8)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389)
at java.desktop/java.awt.Component.processEvent(Component.java:6391)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:722)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:716)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:746)
at java.desktop/java.awt.EventQueue.run(EventQueue.java:744)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
"
第一个window:
public class MainMenu extends JFrame {
public MainMenu(){
setSize(300,600);
JPanel center = new JPanel();
center.setLayout(new GridLayout(3,1));
JButton MainMenuButtonStart = new JButton("Start");
JButton MainMenuButtonContinue = new JButton("Continue");
JButton MainMenuButtonDimensions = new JButton("Dimensions");
center.add(MainMenuButtonStart);
center.add(MainMenuButtonContinue);
center.add(MainMenuButtonDimensions);
ActionDimensions actionDimensions = new ActionDimensions();
MainMenuButtonDimensions.addActionListener(actionDimensions);
add(center, BorderLayout.CENTER);
}
}
第二个window:
import javax.swing.*;
import java.awt.*;
public class Dimensions extends JFrame {
public Dimensions(){
setSize(600,500);
JPanel north = new JPanel();
JLabel labelnorth = new JLabel("Enter Dimensions! Rows and Columns");
north.add(labelnorth);
JPanel center = new JPanel();
JPanel south = new JPanel();
JButton buttonsouth = new JButton("Return to Main Menu");
south.add(buttonsouth);
center.setLayout(new GridLayout(1,2));
TextField rowtextfield = new TextField();
TextField columntextfield = new TextField();
center.add(rowtextfield);
center.add(columntextfield);
add(north,BorderLayout.NORTH);
add(center,BorderLayout.CENTER);
add(south,BorderLayout.SOUTH);
主要功能:
public class Main {
public static void main(String[] args) {
MainMenu mainMenu = new MainMenu();
Dimensions dimensions = new Dimensions();
dimensions.setVisible(false);
mainMenu.setVisible(true);
mainMenu.setDefaultCloseOperation(3);
}
}
动作侦听器:
public class ActionDimensions implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JFrame mainMenu = (JFrame) e.getSource();
JFrame dimensions = (JFrame) e.getSource();
mainMenu.setVisible(false);
dimensions.setVisible(true);
}
}
我认为问题是我试图通过框架使用 getsource() 方法,但如果我不指定该方法,我将无法访问实例(主菜单和维度)。如果是这样,还有什么其他方法可以将 setVisible 方法连接到 ActionListener 内的实例?
这可能是您的问题:
JFrame mainMenu = (JFrame) e.getSource();
JFrame dimensions = (JFrame) e.getSource();
ActionEvent#getSource()
方法 return 是触发操作的 来源 ,这里是一个 JButton,您正在尝试投射 相同 JButton 对象 return 从这个方法中作为两个不同的 JFrames 编辑,这真的没有多大意义,因为,再一次,这个方法没有't return 一个 JFrame,其次,转换不会将一个对象转换为两个不同的对象。如果您需要对 JFrame 的引用,请将其传递到需要的位置,例如为您的 ActionListener class 提供一个采用 JFrame 参数的构造函数:
ActionDimensions actionDimensions = new ActionDimensions(this);
和
public class ActionDimensions implements ActionListener {
private MainMenu mainMenu;
public ActionDimensions(MainMenu mainMenu) {
this.mainMenu = mainMenu;
}
@Override
public void actionPerformed(ActionEvent e) {
// JFrame mainMenu = (JFrame) e.getSource();
// JFrame dimensions = (JFrame) e.getSource();
mainMenu.setVisible(false);
// create a new Dimensions JFrame here?
Dimensions dimensions = new Dimensions();
// .... other code
dimensions.setVisible(true);
}
}
或者,您可以通过调用 SwingUtilities.getWindowAncestor(yourJButton)
.
获取按钮所在的 JFrame
话虽如此,但要明白没有用户会喜欢有多个 windows 推向他们,这就是交换 JFrames 所做的,并且有更好的方法来干净地交换视图,例如使用CardLayout tutorial. Please read The Use of Multiple JFrames, Good/Bad Practice?.
我正在尝试在单击按钮(在本例中为尺寸按钮)时“打开”另一个 JFrame window,就像浏览菜单时一样。我的 2 windows、Main 函数和 ActionListener 是分开的 类。当我单击应该将我重定向到另一个 window 的按钮时,它只是显示一个错误,并没有隐藏第一个 window 并显示第二个。错误是:
"Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: class javax.swing.JButton cannot be cast to class javax.swing.JFrame (javax.swing.JButton and javax.swing.JFrame are in module java.desktop of loader 'bootstrap') at ActionDimensions.actionPerformed(ActionDimensions.java:8) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6626) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3389) at java.desktop/java.awt.Component.processEvent(Component.java:6391) at java.desktop/java.awt.Container.processEvent(Container.java:2266) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5001) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4833) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773) at java.desktop/java.awt.EventQueue.run(EventQueue.java:722) at java.desktop/java.awt.EventQueue.run(EventQueue.java:716) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97) at java.desktop/java.awt.EventQueue.run(EventQueue.java:746) at java.desktop/java.awt.EventQueue.run(EventQueue.java:744) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:743) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) "
第一个window:
public class MainMenu extends JFrame {
public MainMenu(){
setSize(300,600);
JPanel center = new JPanel();
center.setLayout(new GridLayout(3,1));
JButton MainMenuButtonStart = new JButton("Start");
JButton MainMenuButtonContinue = new JButton("Continue");
JButton MainMenuButtonDimensions = new JButton("Dimensions");
center.add(MainMenuButtonStart);
center.add(MainMenuButtonContinue);
center.add(MainMenuButtonDimensions);
ActionDimensions actionDimensions = new ActionDimensions();
MainMenuButtonDimensions.addActionListener(actionDimensions);
add(center, BorderLayout.CENTER);
}
}
第二个window:
import javax.swing.*;
import java.awt.*;
public class Dimensions extends JFrame {
public Dimensions(){
setSize(600,500);
JPanel north = new JPanel();
JLabel labelnorth = new JLabel("Enter Dimensions! Rows and Columns");
north.add(labelnorth);
JPanel center = new JPanel();
JPanel south = new JPanel();
JButton buttonsouth = new JButton("Return to Main Menu");
south.add(buttonsouth);
center.setLayout(new GridLayout(1,2));
TextField rowtextfield = new TextField();
TextField columntextfield = new TextField();
center.add(rowtextfield);
center.add(columntextfield);
add(north,BorderLayout.NORTH);
add(center,BorderLayout.CENTER);
add(south,BorderLayout.SOUTH);
主要功能:
public class Main {
public static void main(String[] args) {
MainMenu mainMenu = new MainMenu();
Dimensions dimensions = new Dimensions();
dimensions.setVisible(false);
mainMenu.setVisible(true);
mainMenu.setDefaultCloseOperation(3);
}
}
动作侦听器:
public class ActionDimensions implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
JFrame mainMenu = (JFrame) e.getSource();
JFrame dimensions = (JFrame) e.getSource();
mainMenu.setVisible(false);
dimensions.setVisible(true);
}
}
我认为问题是我试图通过框架使用 getsource() 方法,但如果我不指定该方法,我将无法访问实例(主菜单和维度)。如果是这样,还有什么其他方法可以将 setVisible 方法连接到 ActionListener 内的实例?
这可能是您的问题:
JFrame mainMenu = (JFrame) e.getSource();
JFrame dimensions = (JFrame) e.getSource();
ActionEvent#getSource()
方法 return 是触发操作的 来源 ,这里是一个 JButton,您正在尝试投射 相同 JButton 对象 return 从这个方法中作为两个不同的 JFrames 编辑,这真的没有多大意义,因为,再一次,这个方法没有't return 一个 JFrame,其次,转换不会将一个对象转换为两个不同的对象。如果您需要对 JFrame 的引用,请将其传递到需要的位置,例如为您的 ActionListener class 提供一个采用 JFrame 参数的构造函数:
ActionDimensions actionDimensions = new ActionDimensions(this);
和
public class ActionDimensions implements ActionListener {
private MainMenu mainMenu;
public ActionDimensions(MainMenu mainMenu) {
this.mainMenu = mainMenu;
}
@Override
public void actionPerformed(ActionEvent e) {
// JFrame mainMenu = (JFrame) e.getSource();
// JFrame dimensions = (JFrame) e.getSource();
mainMenu.setVisible(false);
// create a new Dimensions JFrame here?
Dimensions dimensions = new Dimensions();
// .... other code
dimensions.setVisible(true);
}
}
或者,您可以通过调用 SwingUtilities.getWindowAncestor(yourJButton)
.
话虽如此,但要明白没有用户会喜欢有多个 windows 推向他们,这就是交换 JFrames 所做的,并且有更好的方法来干净地交换视图,例如使用CardLayout tutorial. Please read The Use of Multiple JFrames, Good/Bad Practice?.