Я пытаюсь создать 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);
}
}
Вы не добавляете свою переменную панели в свою 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();
}
});
}
}