2013-10-04 2 views
4

Я ввожу изменения в игру тральщика. Одна из этих вещей - трудность. Мне удалось это сделать и его работу, но поскольку игровая панель (в своем собственном Jpanel) становится больше & меньше (в зависимости от сложности), я не могу автоматически изменять размер JFrame. Я использую:изменить размер JFrame автоматически с помощью JPanel Java

setPreferredSize(new Dimension(WIDTH, HEIGHT)); 

установить начальный размер окна, но это делает его очень маленьким, как в только показывать слово «File» из JMenuBar. Я должен изменить его вручную.

Я попробовал setSize() и вещи вроде frame.pack() в событии ActionListener, но я не могу заставить его изменять размер.

Любые советы по использованию кода/методов.

редактировать: Код размещен

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

Вы, кажется, используете правильные методы, но, вероятно, неправильно. Отправьте свой код. –

+0

Кроме того, вы используете методы на JPanel или JFrame? – Levenal

+0

Использование 'validate();' или 'revalidate();' стремится 'обновить' JFrame/JPanel - вы пытались использовать их? – crazyloonybin

ответ

7

Одна из этих вещей является трудность. Мне удалось это сделать и его работа, но по мере того, как игровая доска (в ее собственной Jpanel) становится больше & меньше (в зависимости от сложности), я не могу получить JFrame до .

и

пытался SetSize() и тому подобные вещи frame.pack() на ActionListener событие, но я не могу показаться, чтобы заставить его изменить.

  • JFrame.pack() работы в случае

    1. что все JComponents представляющие шахты (есть лучшие способы использования JToggleButton) возвращает правильно PreferredSize обратно к родителю (JPanel)

    2. родительский (JPanel), заложенный GridLayout (очень простой)

    3. и есть два способа, как, когда, где JFrame.pack()

      • использования CardLayout, следующий код строки после swithching 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(); 
      } 
     }); 
    } 
} 
+0

спасибо за ваш ответ, но я не понимаю, о чем вы говорите: «там вы пропустите строки кода (не расширяйте JFrame, создайте этот объект как локальную переменную); –

+0

remove' extends JFrame' из 'public class SetupFrame расширяет JFrame {', потому что есть два 'JFrame', один из них никогда не отображается, и для этого 'JFrame' внесены изменения, вам нужно добавить' frame.' перед каждым ' setXxxXxx' и 'add()', в 'IDE' есть красные предупреждения – mKorbel

+0

Спасибо. Я внес изменения, но, к сожалению, JFrame по-прежнему не изменяет размер :-(. –

7

Вот ваша ошибка:

frame.pack();

Зачем вам нужен frame если ваш SetupFrame фактически простирается от JFrame? Измените эту строку только pack(), и она будет работать.

@mKorbel уже отправил полное и очень полезное объяснение по поводу поведения pack() (спасибо).

Update

Также в вашем 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

+0

Спасибо. Я действительно попробовал пакет() но сам он не сработал. Как я уже сказал, я пробовал много вещей и frame.pack(); это была последняя вещь, которую я пробовал :-) –

+0

@AngeKing Вы уверены? Я только что сделал это, и это сработало как прелесть для меня. У меня нет класса 'Board' для проверки поведения при изменении уровня сложности. Пожалуйста, см. Обновленный ответ, я нашел небольшую ошибку. – dic19

+0

Спасибо за подсказку. Я изменил код, и я увидел свою ошибку добавления другого фрейма. он по-прежнему не изменяет размер при изменении уровня сложности, поэтому я рассмотрю ItemListener. –

Смежные вопросы