マインスイーパゲームに変更を加えています。これらの1つは難しさです。私はこれとその動作をなんとか実行できましたが、ゲームボード(独自のJpanel内)が(難易度に応じて)大きくなったり小さくなったりすると、JFrameのサイズを自動的に変更できなくなります。私は使っている:
setPreferredSize(new Dimension(WIDTH, HEIGHT));
ウィンドウの初期サイズを設定しますが、これにより、JMenuBarからWord'File 'のみを表示する場合のように、ウィンドウが非常に小さくなります。手動でサイズを変更する必要があります。
ActionListenerイベントでsetSize()やframe.pack()などを試しましたが、サイズを変更できないようです。
使用するコード/メソッドに関するヒント。
編集:投稿されたコード
package mines;
import Java.awt.BorderLayout;
import Java.awt.Dimension;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import javax.swing.*;
public class SetupFrame extends JFrame {
private final int WIDTH = 600;
private final int HEIGHT = 500;
public JFrame frame;
public JMenuBar menubar;
public JMenu file;
public JMenu levels;
public JMenu help;
public JMenuItem login;
public JMenuItem save;
public JMenuItem resume;
public JMenuItem exit;
public JMenuItem easy;
public JMenuItem medium;
public JMenuItem hard;
private JLabel statusbar;
public JPanel main;
public JPanel buttonPanel;
public JPanel saved;
public JPanel game;
public Board mineGame;
public JButton ngButton;
public JButton undoButton;
public JButton redoButton;
public JTabbedPane tp;
public String[] levelPicker;
public JComboBox levelSelect;
public JFileChooser chooser;
public String filename;
public int difficulty;
public SetupFrame(){
frame = new JFrame();
String filename = JOptionPane.showInputDialog(frame, "Enter Your Name.");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setTitle("Minesweeper");
//menubar, menus, menu items
menubar = new JMenuBar();
setJMenuBar(menubar);
file = new JMenu("File");
help = new JMenu("Help");
menubar.add(file);
menubar.add(help);
login = new JMenuItem("Login..");
save = new JMenuItem("Save..");
resume = new JMenuItem("Resume..");
exit = new JMenuItem("Exit");
file.add(login);
file.add(save);
file.add(resume);
file.addSeparator();
file.add(exit);
statusbar = new JLabel("");
chooser = new JFileChooser(); // new File Chooser for saved tab
undoButton = new JButton(" Undo "); //undo Button for game panel
ngButton = new JButton(" New Game ");//new game Button for game panel
redoButton = new JButton(" Redo");//redo Button for game panel
main = new JPanel(new BorderLayout()); //new panel for main game
//main.add(mineGame, BorderLayout.CENTER); //add instance mineGame to main panel
game = new JPanel(new BorderLayout());// new panel for game tab
main.add(game, BorderLayout.CENTER); //add the mineGames panel to game panel
game.add(statusbar, BorderLayout.SOUTH); //add statusbar to bottom of game panel
//game.add(button, BorderLayout.NORTH); // add buttons (eventually be redo, undo, new game)
saved = new JPanel(); // create new panel for the saved tab
saved.add(chooser);//add the File Chooser to the saved tab
String[] levelPicker = {"Easy", "Medium", "Hard"};
levelSelect = new JComboBox(levelPicker);
levelSelect.setSelectedIndex(0);
//levelSelect.addActionListener(this);
buttonPanel = new JPanel();
buttonPanel.add(undoButton);
buttonPanel.add(ngButton);
buttonPanel.add(redoButton);
buttonPanel.add(levelSelect);
main.add(buttonPanel, BorderLayout.NORTH);
//create & add the tabs
tp = new JTabbedPane();
tp.addTab ("Game", main);
tp.addTab ("Saved", saved);
tp.addTab ("Statistics", null);
add(tp);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setResizable(true);
setVisible(true);
frame.pack();
class listener implements ActionListener{
public void actionPerformed (ActionEvent e)
{
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
}
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker == "Easy"){
difficulty = 0;
newMineGame();
}
if (picker == "Medium"){
difficulty = 1;
newMineGame();
frame.pack();
}
if (picker == "Hard"){
difficulty = 2;
newMineGame();
frame.pack();
}
}
private void newMineGame() {
game.removeAll();
mineGame = new Board(statusbar, difficulty);
game.add(mineGame, BorderLayout.CENTER);
game.add(statusbar, BorderLayout.SOUTH);
repaint();
}
}
ngButton.addActionListener(new listener());
undoButton.addActionListener(new listener());
redoButton.addActionListener(new listener());
levelSelect.addActionListener(new listener());
}
public static void main(String[] args) {
new SetupFrame();
}
これらの1つは難しさです。私はこれとその動作をなんとか実行できましたが、ゲームボード(独自のJpanel内)が(難易度に応じて)大きくなったり小さくなったりすると、JFrameのサイズを自動的に変更できなくなります。
そして
actionListenerイベントでsetSize()やframe.pack()などを試しましたが、サイズを変更できないようです。
JFrame.pack()
は
地雷を表すすべてのJComponents
(JToggleButton
を使用する最良の方法があります)は、適切にPreferredSize
を親(JPanel
)に返します。
gridLayoutによって配置された親(JPanel)(非常に単純)
JFrame.pack()
を行う方法、時期、場所は2つあります。
CardLayout
を使用します。Card
を切り替えた後の次のコード行はJFrame.pack()
です。
古いJPanel
を(JFrame
から)削除して新しいものに置き換えたら、JFrame.(re)validate()
、JFrame.repaint()
、およびJFrame.pack()
を呼び出す必要があります最後のコード行として
別の問題があるかもしれません。重要なのは、JFrame.setResizable(false);
の設定がある場合のコードの順序です。
編集後
使用 Cardlayout
コード行がありません(JFrame
を拡張しないでください。このオブジェクトを_Local variable
_として作成してください)JFrame.(re)validate()
、JFrame.repaint()
、およびJFrame.pack()
private void newMineGame() {
の最後のコード行として
しかし、私はあなたが何を意味するのか理解していません: "コード行がありません(JFrameを拡張しないでください。このオブジェクトをローカル変数として作成してください);
コードは
_import javax.swing.*;
public class SetupFrame {
private JFrame frame;
private JMenuBar menubar = new JMenuBar();
private Board mineGame;
public SetupFrame() {
//there add required JComponents
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setTitle("Minesweeper");
frame.setJMenuBar(menubar);
frame.add(mineGame);
//frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
//frame.setResizable(true);//not neccessary
frame.pack();
frame.setVisible(true);
}
private void newMineGame() {
//remove old Board
//add a new Board
frame.validate();
frame.repaint();
frame.pack();
}
private static void main(String[] args) {
Java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new SetupFrame();
}
});
}
}
_
ここにあなたの間違いがあります:
frame.pack();
frame
が実際にSetupFrame
から拡張されているのに、なぜJFrame
が必要なのですか?この行をpack()
だけ変更すると、機能します。
@mKorbelは、pack()
の動作に関する完全で非常に役立つ説明をすでに投稿しています(ありがとうございます)。
更新
また、listener
クラスでは、JButton
が押されたときに次の例外が発生します。
Java.lang.ClassCastException: javax.swing.JButton cannot be cast to javax.swing.JComboBox
これを回避するには、この小さな変更を加える必要があります。
class listener implements ActionListener{
public void actionPerformed (ActionEvent e) {
if(e.getSource() == ngButton){
//JOptionPane.showInputDialog(frame, "Do You want To Save");
newMineGame();
} else if(e.getSource() instanceof JComboBox){ // add this else-if block
JComboBox cb = (JComboBox)e.getSource();
String picker = (String)cb.getSelectedItem();
if (picker.equals("Easy")){ // <-- picker == "Easy" is not the proper way to compare string, use equals() method instead
difficulty = 0;
newMineGame();
}
if (picker.equals("Medium")){
difficulty = 1;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
if (picker.equals("Hard")){
difficulty = 2;
newMineGame();
//frame.pack(); <--- again, just use pack();
pack();
}
}
}
またはさらに良いことに、 ItemListener を実装して、代わりにJComboBox
を使用してActionListener
選択の変更をリッスンします