2017-01-25 5 views
0

В настоящее время я работаю над маленькой игрой, но я только столкнулся с проблемой:Draw прямоугольника при нажатии JButton

У меня есть три класса, то первые из них является JFrame:

public class Game 
{ 

    public static void main(String[] args) 
    { 
     new Game().gui(); 
    } 


    public void gui() 
    { 
     DrawPanel panel = new DrawPanel(); 
     JFrame frame = new JFrame("Test"); 
     //frame.add(panel); 
     frame.add(new MainMenu()); 
     frame.setSize(800, 700); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
    } 
} 

Теперь у меня есть два другие классы, один - mainMenu, в настоящее время состоящий только из одного JButton. Я решил сделать меню своим классом, потому что позже я хочу вызвать меню, нажав escape, но проблема в том, что (по причинам тестирования) я хочу нарисовать прямоугольник при нажатии «start». Я пробовал разные подходы, но ничего не происходит.

public class MainMenu extends JPanel implements ActionListener 
{ 

    GamePanel panel = new GamePanel(); 

    public MainMenu() 
    { 

     setLayout(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 

     JButton b1 = new JButton("Start"); 
     c.fill = GridBagConstraints.HORIZONTAL; 
     c.ipadx = 200; 

     b1.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       setVisible(false); 
      } 
     }); 
     add(b1, c); 

    } 

} 


public class DrawPanel extends JPanel 
{ 

    public void paint(Graphics g) 
      { 
      g.drawRect (10, 10, 200, 200); 
      } 

} 
+0

У вас '//frame.add (панель);', поэтому ничего не нарисовано ... –

+0

Я знаю. Но это все равно не работает. – JonDoeMaths

+0

Я думаю, вы должны '@ переопределить' метод' paintComponent'. Вы можете увидеть [пользовательскую роспись в Swing] (https://docs.oracle.com/javase/tutorial/uiswing/painting/). Ваш прослушиватель кнопок является отдельным вопросом, чем в настоящее время рисует что-либо. –

ответ

1

Есть несколько ошибок, которые я нашел в своем коде:

  1. Вы не добавляя свои DrawPanel к чему-либо, потому что эта линия

    frame.add(panel); 
    

    комментируется, так, что ведет нас к следующей проблеме:

  2. Вы переопределяете paint() метод вместо paintComponent(), а также не забудьте позвонить

    super.paintComponent(); 
    

    в самом начале этого метода. Без этого вы не позволяете вашему коду продолжать рисовать остальные компоненты. См Custom painting in Swing

  3. , что до сих пор не делает ничего появляться, потому что вы не объявили местоположение для DrawPanel и, таким образом, он принимает JFrame По умолчанию Layout Manager который BorderLayout и это по умолчанию место, когда не указано в CENTER, а также вы добавляете к нему new MainMenu() в той же позиции, что заменяет панель DrawPanel, так как только один компонент может существовать в одном и том же положении.

    Вместо этого попробуйте поместить DrawPanel в CENTER и MainMenu в SOUTH. Он должен теперь выглядеть следующим образом:

    enter image description here

  4. Не забудьте поставить свою программу на Event Dispatch Thread (EDT), написав метод main следующим образом:

    public static void main(String[] args) { 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          //Your constructor here 
         } 
        }); 
    } 
    
  5. Вы реализующий ActionListener на MainMenu, но не реализует его методы, удаляет его или реализует метод actionPerformed и перемещает код внутри прослушивателя действий b1. Тем не менее, я настоятельно рекомендую вам взять на Should your class implement ActionListener or use an object of an anonymous ActionListener class тоже

  6. Вы играете с MainMenu «s JPanel видимости, вместо этого вы должны попробовать использовать CardLayout или рассмотреть возможность использования JDialogs.

    Для примера я хотел бы сделать JDialog и поместить JButton там, так что она будет открыта JFrame с Rectangle нарисованной в нем.

Теперь код, который сделал вывод выше и выполняет все рекомендации (но # 6):

import java.awt.BorderLayout; 
import java.awt.Graphics; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class Game { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new Game().gui(); 
      } 
     }); 
    } 

    public void gui() { 
     DrawPanel panel = new DrawPanel(); 
     JFrame frame = new JFrame("Test"); 
     frame.add(panel, BorderLayout.CENTER); 
     frame.add(new MainMenu(), BorderLayout.SOUTH); 
     frame.setSize(400, 300); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
    } 
} 

class MainMenu extends JPanel { 

// GamePanel panel = new GamePanel(); 

    public MainMenu() { 

     setLayout(new GridBagLayout()); 
     GridBagConstraints c = new GridBagConstraints(); 

     JButton b1 = new JButton("Start"); 
     c.fill = GridBagConstraints.HORIZONTAL; 
     c.ipadx = 200; 

     b1.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       setVisible(false); 
      } 
     }); 
     add(b1, c); 
    } 
} 

class DrawPanel extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawRect(10, 10, 200, 200); 
    } 
} 

Как было предложено в комментариях @MadProgrammer, вы можете также переопределить getPreferredSize() метод вашего DrawPanel, а затем позвонить frame.pack():

Ваш DrawPanel класс должен выглядеть следующим образом:

class DrawPanel extends JPanel { 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawRect(10, 10, 200, 200); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(400, 300); 
    } 
} 
+1

Я бы также предложил переопределить 'getPreferredSize'' DrawPanel', он предоставит дополнительные подсказки макета, которые могут помочь, хороший ответ в противном случае;) – MadProgrammer

+0

@MadProgrammer спасибо, я отредактировал ответ, чтобы добавить вашу рекомендацию, не могли бы вы проверить и скажите мне, было ли это то, о чем вы говорили? – Frakcool

+1

Прохладный :) ....... – MadProgrammer

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