通过从其他类调用的方法添加新的JLabel

时间:2018-09-21 15:35:45

标签: java swing awt jlabel

我试图通过另一个类中调用的方法向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发生时被调用的。我对添加内容的理解不正确吗?

1 个答案:

答案 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