JFrame.dispose ();не закрывая рамку - PullRequest
0 голосов
/ 20 ноября 2018

так что я пытаюсь сделать так, чтобы, если эти две фигуры касались друг друга, окно закрывалось.Вот первая часть

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();

}

Итак, ясделал это там, где объект «hitcan» движется вниз по экрану, и когда он касается объекта, окно должно закрываться.Когда оператор my if (для, если координаты y двух объектов равны) вызывает публичный эпос void, он должен «активировать» оператор if для if complete = = 1 и избавиться от фрейма, но по какой-то причине он не 'т

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

Итак, я предполагаю, что этот (ранее удаленный) код куда-то уходит в ваш код обработчика ключей 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 будет вызываться часто (если вы выполняете анимацию), то есть вы постоянно сбрасываете Timer. Состояние Timer никогда не должно изменяться внутри paintComponent. Вместо этого он должен управлять другими средствами, такими как конструктор или методы start / stop

KeyListener сейчас плохой выбор. Он страдает от ряда хорошо известных и задокументированных ошибок. Лучшее всестороннее решение - использовать API связывания клавиш , который был разработан, чтобы помочь решить эти проблемы надежным и надежным способом

0 голосов
/ 20 ноября 2018

Вы можете использовать

f.setVisible(false)

Это просто скрывает окно, а f.dispose() удаляет реальный объект.

Если вы хотите, чтобы он действовал как вынажмите кнопку X, затем используйте это:

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

(получено от Как программно закрыть JFrame )

(f является вашим JFrame)

...