JFrame.dispose();不关闭框架
JFrame.dispose(); not closing the frame
所以我试图让它在这两个形状相互接触时 window 闭合。这是第一部分
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" 对象向下移动屏幕的位置,当它接触到对象时 window 应该关闭。当我的 if 语句(如果两个对象的 y 坐标相等)调用 public void epic 时,它应该 "activate" if 语句 if complete is == 1 并处理框架但是由于某种原因,它没有
你可以使用
f.setVisible(false)
这只是隐藏了 window,f.dispose()
删除了实际对象。
如果你想让它像你点击 X 按钮一样,那么使用这个:
f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
(来自 How to programmatically close a JFrame)
(f
是你的 JFrame)
所以,我假设这个(以前,现在已删除)代码在您的 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
"should" 会向感兴趣的各方生成有关其状态更改的事件通知。
为此,我们需要一个观察者模式!
让我们从一个简单的 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);
}
}
现在,当您处于 "completed" 状态时,您可以通知相关方...
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);
}
在许多层面上都是一个坏主意。 Paint 应该绘制组件的当前状态,没有别的,它不应该决定组件的状态。这属于你的主循环
还有...
time.start();
我无法开始告诉你这有多可怕。 paintComponent
将经常被调用(如果您正在执行动画),这意味着您不断地重置 Timer
。 Timer
的状态不应该在 paintComponent
中被修改。相反,它应该通过其他方式进行控制,例如构造函数或 start/stop 方法
KeyListener
现在是一个糟糕的选择。它有许多众所周知和记录在案的缺点。更好的全面解决方案是使用 Key Bindings API,它旨在以可靠和稳健的方式帮助解决这些问题
所以我试图让它在这两个形状相互接触时 window 闭合。这是第一部分
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" 对象向下移动屏幕的位置,当它接触到对象时 window 应该关闭。当我的 if 语句(如果两个对象的 y 坐标相等)调用 public void epic 时,它应该 "activate" if 语句 if complete is == 1 并处理框架但是由于某种原因,它没有
你可以使用
f.setVisible(false)
这只是隐藏了 window,f.dispose()
删除了实际对象。
如果你想让它像你点击 X 按钮一样,那么使用这个:
f.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
(来自 How to programmatically close a JFrame)
(f
是你的 JFrame)
所以,我假设这个(以前,现在已删除)代码在您的 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
"should" 会向感兴趣的各方生成有关其状态更改的事件通知。
为此,我们需要一个观察者模式!
让我们从一个简单的 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);
}
}
现在,当您处于 "completed" 状态时,您可以通知相关方...
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);
}
在许多层面上都是一个坏主意。 Paint 应该绘制组件的当前状态,没有别的,它不应该决定组件的状态。这属于你的主循环
还有...
time.start();
我无法开始告诉你这有多可怕。 paintComponent
将经常被调用(如果您正在执行动画),这意味着您不断地重置 Timer
。 Timer
的状态不应该在 paintComponent
中被修改。相反,它应该通过其他方式进行控制,例如构造函数或 start/stop 方法
KeyListener
现在是一个糟糕的选择。它有许多众所周知和记录在案的缺点。更好的全面解决方案是使用 Key Bindings API,它旨在以可靠和稳健的方式帮助解决这些问题