我不知道我做了什么,或者出了什么問題,但是我在最近一段時間所做的更改使我的 JPanel 完全不可見。它嵌套的 JFrame 仍然會改變大小以容納它,我仍然可以切換組合框中的內容。
無奈之下,我嘗試用單個按鈕替換 SnakeSettingsPanel 類的內容,但同樣的事情發生了 - 完全不可見,但我仍然可以與其互動。我認為這可能是計算機錯誤,所以我嘗試重新啟動,但仍然沒有。當我嘗試在 JPanel 之外的框架中添加一個按鈕時,它作業得很好。我究竟做錯了什么?
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SnakeSettingsPanel extends JPanel {
public boolean quit = false;
public boolean play = false;
public int width = 20;
public int height = 15;
public Speed speed = Speed.SLOW;
public JTextField wField;
public JTextField hField;
public JComboBox<Speed> sField;
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setTitle("Snake");
SnakeSettingsPanel settings = new SnakeSettingsPanel();
jf.add(settings);
jf.pack();
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public SnakeSettingsPanel() {
setLayout(new GridBagLayout());
// @author Create our labels.
JLabel wLabel = new JLabel("Width:");
JLabel hLabel = new JLabel("Height:");
JLabel sLabel = new JLabel("Speed:");
GridBagConstraints p = new GridBagConstraints();
p.gridx = 0;
p.gridy = 0;
p.insets = new Insets(10, 10, 10, 10);
// @author Create the buttons, and add listeners
JButton y = new JButton("Play");
JButton n = new JButton("Quit");
y.addActionListener(new PlayListener());
n.addActionListener(new QuitListener());
// @author Create text fields for height/width
wField = new JTextField(15);
wField.setText("20");
hField = new JTextField(15);
hField.setText("15");
// @author Creates a combobox for selecting speed.
Speed[] speeds = {Speed.SLOW, Speed.MEDIUM, Speed.FAST};
sField = new JComboBox<Speed>(speeds);
// @author Stitch everything into the panel.
add(wLabel, p);
p.gridx = 1;
add(wField, p);
p.gridx = 0;
p.gridy = 1;
add(hLabel, p);
p.gridx = 1;
add(hField, p);
p.gridx = 0;
p.gridy = 2;
add(sLabel, p);
p.gridx = 1;
add(sField, p);
p.gridx = 0;
p.gridy = 3;
add(y, p);
p.gridx = 1;
add(n, p);
setVisible(true);
}
public boolean getPlay() {
return play;
}
public boolean getQuit() {
return quit;
}
// @author Returns all settings as a SnakeSettings object
public SnakeSettings getSettings() {
return new SnakeSettings(width, height, speed);
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public Speed getSpeed() {
return speed;
}
// @author Sends out the word to start a new game.
public class PlayListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
quit = false;
play = true;
width = Integer.parseInt(wField.getText());
height = Integer.parseInt(hField.getText());
speed = (Speed) sField.getSelectedItem();
}
}
// @author Sends out the word to shut down the program.
public class QuitListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
quit = true;
play = false;
}
}
}
uj5u.com熱心網友回復:
讓這成為一個關于為什么應該避免將模型(您的應用程式的資料)與視圖(它的顯示方式)混合在一起的教訓。你SnakeSettingsPanel目前兩者都是。
- 為模型,它包含3個重要領域:
width,height,和speed。 - 作為 View,它是一個完整的 JPanel。JPanels 有很多你應該避免直接接觸的欄位。包括
widthandheight,通常通過getHeightand訪問getWidth- 您正在使用始終回傳相同的內置值 20 和 15 的版本覆寫它(直到用戶通過他們看不到的 UI 更改這些值)。
在快速的解決辦法是重新命名您的當前getWidth()和getHeight()避免沖突的內置getWidth()和getHeight()父JPanel類的方法。打電話給他們getMyWidth(),getMyHeight()然后突然一切正常。
該更好的解決辦法是在一個完全洗掉這些領域和方法,并保存自己的模型屬性SnakeSettings的屬性。當用戶點擊播放時更新它,并在通過 請求時回傳它getSettings()。您的代碼更少,與您的父JPanel類發生意外名稱沖突的機會更少。這看起來像:
// SnakeSettingsPanel, before
public int width = 20;
public int height = 15;
public Speed speed = Speed.SLOW;
public int getWidth() { // <-- clashes with superclass
return width;
}
public int getHeight() { // <-- clashes with superclass
return height;
}
public Speed getSpeed() {
return speed;
}
public SnakeSettings getSettings() {
return new SnakeSettings(width, height, speed);
}
// SnakeSettingsPanel, after
SnakeSettings settings = new SnakeSettings();
public SnakeSettings getSettings() {
return settings;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/396236.html
上一篇:無法檢測與多邊形的碰撞
