Начать JPanel из отдельного класса (начинающий)

1

Я пытаюсь создать JPanels в отдельном классе, чтобы вызывать их отдельно и добавлять к нему разные элементы. Пожалуйста, скажите мне, что я делаю неправильно?

MyFrame.java

import javax.swing.*;
import java.awt.*;

public class MyFrame extends JFrame {

    public static void main(String[] args) {

        MyFrame frame = new MyFrame();
        frame.setVisible(true);

    }

    public MyFrame() {

       setTitle("MyFrame");
       setSize(300, 200);
       setLocationRelativeTo(null);
       setDefaultCloseOperation(EXIT_ON_CLOSE);

       MyPanel panel = new MyPanel();

       JButton testButton = new JButton("Test");
       panel.add(testButton);

    }

}

MyPanel.java

import javax.swing.*;
import java.awt.*;

class MyPanel extends JPanel {

    public MyPanel() {

        this.setOpaque(true);
        this.setVisible(true); 

    }

}
Теги:
swing
jpanel
jframe

1 ответ

5
Лучший ответ

Вы не добавляете свою переменную панели в свою JPrame contentPane.

Добавить:

public MyFrame() {
   setTitle("MyFrame");
   // setSize(300, 200); // let avoid this
   setDefaultCloseOperation(EXIT_ON_CLOSE);

   MyPanel panel = new MyPanel();

   JButton testButton = new JButton("Test");
   panel.add(testButton);
   add(panel);  // *** here
   pack();  // this tells the layout managers to do their thing
   setLocationRelativeTo(null);  
   setVisible(true);
}

В качестве примечания:

public MyPanel() {

    this.setOpaque(true);
    this.setVisible(true); 

}

JPanels непрозрачны и видимы по умолчанию, поэтому вызовы метода внутри конструктора MyPanel ничего не приносят.

Замечание 2: Я редко когда-либо расширяю JFrame или любое другое окно верхнего уровня (за исключением JApplet, если я вынужден использовать один из них), так как я редко меняю врожденное поведение окна. Лучше я думаю, чтобы создать мои окна верхнего уровня (т.е. Мои JFrames), когда это необходимо.

Замечание 3: Всегда старайтесь запустить свой графический интерфейс Swing в потоке событий Swing. Ну действуй...

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            MyFrame frame = new MyFrame();
            frame.setVisible(true);
        }
    });
}

редактировать
Ты спрашиваешь:

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

Мне нравится переопределить метод JPanel getPreferredSize() и вернуть ему значение, которое имеет смысл.

Например, вы можете сделать что-то вроде этого, чтобы убедиться, что ваш графический интерфейс не PREF_W по PREF_H:

import java.awt.Dimension;

import javax.swing.*;

public class ShowGetPreferredSize extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;

   @Override
   public Dimension getPreferredSize() {
      Dimension superSize = super.getPreferredSize();
      if (isPreferredSizeSet()) {
         return superSize;
      }
      int w = Math.max(superSize.width, PREF_W);
      int h = Math.max(superSize.height, PREF_H);
      return new Dimension(w, h);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("ShowGetPreferredSize");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(new ShowGetPreferredSize());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
  • 0
    Спасибо. Тупая ошибка ^^ Вы написали, давайте не будем устанавливать размер. Можете ли вы сказать мне, как я могу упаковать его, но установить минимальный размер кадра?
  • 0
    @muni: пожалуйста, посмотрите Eidt.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню