我试图通过另一个类中调用的方法向JPanel中添加新的JLabel。
第1类:
public class AppFrame extends JFrame {
// CardGame
//Making private objects to access?\
private MainPanel mainPanel = new MainPanel();
public AppFrame() {
super("BlackJack Cardgame");
setBounds(100, 100, 640, 640);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
add(new StatusBar(), BorderLayout.SOUTH);
add(new MainPanel(), BorderLayout.CENTER);
add(new StatusBar(), BorderLayout.NORTH);
setVisible(true);
//Does not correctly add label
mainPanel.testMethod();
}
public MainPanel getMainPanel() {
return mainPanel;
}
第2类:
public class MainPanel extends JPanel {
Border blackBorder = BorderFactory.createLineBorder(Color.BLACK);
GridBagConstraints gbc = new GridBagConstraints();
public void testMethod() {
System.out.println("test method");
this.add(new JLabel("test"));
}
public MainPanel() {
setLayout(new GridBagLayout());
ImageIcon icon = new ImageIcon(getClass().getResource("/images/ACE_CLUBS.jpg"));
gbc.gridx = 0;
gbc.gridy = 0;
add(new JLabel(icon),gbc);
ImageIcon icon2 = new ImageIcon(getClass().getResource("/images/TWO_CLUBS.jpg"));
gbc.gridx = 1;
gbc.gridy = 0;
add(new JLabel(icon2),gbc);
gbc.gridx=0;
gbc.gridy=1;
//correctly adds label.
testMethod();
}
如果从Class 2(我要在其中添加内容的框架)中调用该方法,则它将按预期工作。但是,如果我尝试从类1调用该方法,它将不会添加标签。 我确信该方法是在sysout发生时被调用的。我对添加内容的理解不正确吗?
答案 0 :(得分:0)
在第一种情况下,将标签添加到面板,然后将面板添加到框架,然后使框架可见。当使框架可见时,将调用布局管理器,并根据布局管理器的规则为框架上的所有组件指定大小和位置。
但是,在第二种情况下,您试图将标签添加到可见的GUI。
setVisible(true);
//Does not correctly add label
mainPanel.testMethod();
您永远不会调用布局管理器,因此组件的大小为(0,0),因此无需绘制任何内容。
每当您从可见的GUI添加(或删除)组件时,基本逻辑将是:
panel.add(...);
panel.revalidate(); // invokes the layout manager.
panel.repaint();
因此,在testMethod()中,您都需要添加revalidate()和repaint()。
。我确定该方法会在sysout发生时被调用
另一个问题是您的getMainPanel()方法将无法工作,因为您有两个对MainPanel类的引用:
private MainPanel mainPanel = new MainPanel(); // this is just sitting in memory
public AppFrame() {
...
add(new MainPanel(), BorderLayout.CENTER); // this is added to the frame.
因此,您要在仅位于内存中且尚未添加到框架的面板上调用testMethod()方法。
摆脱类的第二个实例。您应该做的是:
private MainPanel mainPanel = new MainPanel();
public AppFrame() {
...
add(mainPanel, BorderLayout.CENTER);
它将按预期工作。
我感到很惊讶,因为您的面板使用的是GridBagLayout
,但是在添加标签时您从未指定GridBagConstraint
。