如何配置jframe

时间:2016-05-26 20:59:38

标签: java swing jframe jpanel

我在类中有一个jframe对象,我希望能够从我的jpanel类(显然我附加到框架)中关闭框架。无论如何,我尝试在我的jpanel中创建一个实例字段,其中jframe对象有一个实例字段,然后创建一个方法,我将在jframe类中调用我生成的jframe对象的参数,这样我就可以使jpanel实例字段为与jframe对象相同的对象。然后我调用了实例field.dispose();希望它会关闭框架。任何想法将不胜感激!

如果这是一个很难理解的例子:

public class example extends jFrame
{
public static void main(String[]args)
{
    examplePanel ep = new examplePanel();
    example e = new example(ep);

}
/**
 * Constructor for objects of class example
 */
 public example(examplePanel ep)
 {
    //code that handles my frame settings
 }
 }

  public class examplePanel extends jPanel implements ActionListener
  {
   private example e;
   private boolean checkWin;
   public void actionPerformed(ActionEvent e)
   {
    if(this.checkWin())
   {
       setVisible(false);
       e.dispose();
       //^this line of code is supposed to dispose of the frame but it does  not
   }  
   }

   public void getExample(example e)
   {
    this.e = e;
   }

  }

1 个答案:

答案 0 :(得分:4)

你的代码和问题很难理解,因为你有一个没有添加到JButton或JMenuItem的ActionListener,你创建了一个JFrame对象和一个JPanel,但是从来没有观察到将面板添加到框架中。您为JPanel提供了一个“示例”变量,但从未为它指定可视化JFrame的引用,您似乎没有设置JFrame的默认关闭操作,因此您上面写的JFrame应该是不可关闭的。从您的代码看起来,JPanel中的examplePanel e变量实际上应该为null,因此调用它上面的任何方法都应该抛出NullPointerException,除非您为它分配正确的JFrame对象引用,但是没有向我们展示。

我自己,在需要的时候,我会从Swing本身获得顶级窗口,例如:

        @Override
        public void actionPerformed(ActionEvent e) {
            // get the top-level window that is displaying this JPanel
            Window win = SwingUtilities.getWindowAncestor(this);
            if (win != null) {
                win.dispose();  // dispose of it
            }
        }

例如:

import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.*;
import javax.swing.*;

public class CloseFromJPanel extends JPanel implements ActionListener {
    private static final int PREF_W = 400;
    private static final int PREF_H = 300;

    public CloseFromJPanel() {
        JButton closeButton = new JButton("Close Me");
        closeButton.addActionListener(this);

        add(closeButton);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // get the top-level window that is displaying this JPanel
        Window win = SwingUtilities.getWindowAncestor(this);
        if (win != null) {
            win.dispose();  // dispose of it
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Close From JPanel");

        // GUI will exit when the JFrame is closed
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new CloseFromJPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

}

此代码适用于JFrames和JDialogs中的JButton,但不适用于JMenuItems或JApplets(我不认为)。或者,如果您要做的就是结束应用程序,那么您只需从actionPerformed方法中调用System.exit(0)即可。如果您绝对想要使用JFrame的字段来执行此操作,那么您需要将对JFrame的引用传递到JPanel中,可能使用构造函数参数,并且可能传入this

如果这没有帮助,请创建和发布真实代码,而不是那种代码,我们可以编译,运行和实际测试的代码,MCVE(请查看链接) 。

其他问题:

  • 您的代码不符合Java命名标准,因为类名都应以大写字母开头。请谷歌这个并研究它,因为如果你的代码遵循标准,其他人,包括我们和你未来的自己,将能够更好地理解你的代码。
  • 您很少想要从JFrame扩展,因为您很少需要改变它的先天行为。通常,您可以在需要的时间和地点创建和使用JFrame或JDialog。