JFrame.dispose();没有关闭框架

时间:2018-11-20 00:14:15

标签: java swing jframe dispose

所以我想让它在这两个形状相互接触的地方关闭窗口。这是第一部分

public class Mayflower {

JFrame f = new JFrame();

public static void main(String[] args) {

    Mayflower bob = new Mayflower();
    bob.Start();

}

private void Start(int clothes, int food, int repair, int money) {
    int complete = 0;
    Mayflower bob = new Mayflower();
    //JOptionPane.showMessageDialog(null, "Your equipment:\nClothes - " + clothes + "\nFood - " + food + "\nrepair equipment - " + repair + "\nMoney left - $" + money);
    bob.epic(complete);
}

public void epic(int complete) {


    if (complete == 0){
    Iceberg Tim = new Iceberg();

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);

    }

    if(complete == 1){
        System.out.println("odeyladoeijoo");
        f.dispose();
     }


}

}

然后调用迷你游戏所在的构造函数冰山,我删除了所有与动作无关的动作输入:

package mayflower;


public class Iceberg extends JPanel implements ActionListener, KeyListener {

Timer time = new Timer(5, this);
int x = 260;
int y = 500;
int velx = 0;
int vely = 0;

int hitscany = -4000;
int hitscanvely = -1;


public Iceberg() {

    time.start();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);

}

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

g.setColor(MyColor1);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
        int complete = 1;
        Mayflower bob = new Mayflower();
        bob.epic(complete);

    }

    time.start();

}

所以我到达了“ hitscan”对象在屏幕上向下移动的位置,当它碰到该对象时,窗口应该关闭了。当我的if语句(因为两个对象的y坐标是否相等)调用公共空空史诗时,它应该“激活” if complete的if语句== 1并处理框架,但由于某种原因,它不会“ t

2 个答案:

答案 0 :(得分:0)

因此,我认为,此(以前已被删除)的代码可以在您的Iceberg密钥处理程序代码中的某些位置...

if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);
}

这突出了许多问题。首先,您要创建Mayflower的另一个实例,这是JFrame的另一个实例,这是要处理的内容,而不是原始帧。

Iceberg确实不需要与Mayflower进行交互,这超出了责任范围。取而代之的是,Iceberg应该向感兴趣的各方生成有关其状态更改的事件通知。

为此,我们需要一个观察者模式!

让我们从一个简单的interface开始,它描述Iceberg愿意发出的所有通知...

public interface GameListener {
    public void completed(Iceberg berg);
}

接下来,我们需要某种方法来管理Iceberg中的这些侦听器...

public class Iceberg extends JPanel implements ActionListener, KeyListener {

    private List<GameListener> listeners = new ArrayList<>(25);


    public void addGameListener(GameListener listener) {
        listeners.add(listener);
    }

    public void removeGameListener(GameListener listener) {
        listeners.remove(listener);         
    }

最后,通过某种方式生成通知...

public class Iceberg extends JPanel implements ActionListener, KeyListener {
    //...       
    protected void fireCompleted() {
        for (GameListener listener : listeners) {
            listener.completed(this);
        }
    }

现在,当您处于“完成”状态时,您可以通知感兴趣的各方...

if ((((x - icex)) >= -40 && ((x - icex) - 180) <= -130) && (((y - icey)) >= -60 && ((y - icey) - 180) <= -130)) {
    fireCompleted();
}

现在,在您的start方法中,您只需创建一个Iceberg的实例,注册一个GameListener并将其全部启动...

private void Start(int clothes, int food, int repair, int money) {
    Iceberg Tim = new Iceberg();
    Tim.addGameListener(new GameListener() {
        @Override
        public void completed(Iceberg berg) {
            f.dispose();
        }
    });

    f.add(Tim);
    f.setVisible(true);
    f.setSize(600, 600);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setTitle("SAILIN BABEEEEY");
    f.setLocation(600, 200);
}

观察...

好的,您的代码示例有很多值得担心的地方,但让我们从...开始吧。

@Override
public void paintComponent(Graphics g) {

    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.RED);
    g.fillRect(x, y, 40, 60);

    g.setColor(Color.GRAY);
    g.fillRect(0, hitscany, 650, 0);

    if (y == hitscany) {
        int complete = 1;
        Mayflower bob = new Mayflower();
        bob.epic(complete);

    }

    time.start();

}
  • paintComponent永远不要是public,没有人可以直接调用它。
  • 您声明但从未使用g2

这个...

if (y == hitscany) {
    int complete = 1;
    Mayflower bob = new Mayflower();
    bob.epic(complete);

}

在许多层面上都是个坏主意。绘制应该绘制组件的当前状态,别无其他,它不应该对组件的状态做出决定。这属于您的主循环

然后...

time.start();

我无法告诉你这有多可怕。 paintComponent将经常被调用(如果您正在执行动画),这意味着您将不断重置TimerTimer的状态永远不能在paintComponent内部进行修改。相反,它应该通过其他方式进行控制,例如构造函数或启动/停止方法

KeyListener如今是一个糟糕的选择。它遭受了许多众所周知且有据可查的短期缺陷。更好的全方位解决方案是使用Key Bindings API,该this is how it works旨在帮助您以可靠且健壮的方式解决这些问题

答案 1 :(得分:-1)

您可以使用

f.setVisible(false)

这只是隐藏窗口,而f.dispose()删除实际对象。

如果您希望它像单击X按钮一样起作用,请使用以下方法:

f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

(从How to programmatically close a JFrame获得)

({f是您的JFrame)