0

The question is that I cannot add JPanel and JLabel in the Frame at the same time. When i using following code, only MyPanel will be visible. myFrame.add(myLabel);myFrame.add(myPanel);myFrame.setVisible(true);

when I execute: myFrame.add(myLabel);myFrame.setVisible(true);myFrame.add(myPanel); only myLabel will be visible.

import javax.swing.*;
    import java.awt.*;
    public class Main {
        public static void main(String[] args) {
            MyFrame myFrame =  new MyFrame();
            MyLabel myLabel  = new MyLabel();
            MyPanel myPanel = new MyPanel();
            myFrame.add(myLabel);
            myFrame.add(myPanel);
            myFrame.setVisible(true);
        }
    }


public class MyFrame extends JFrame {
    MyFrame() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //exit out of application.
        //https://docs.oracle.com/javase/7/docs/api/javax/swing/JFrame.html#setDefaultCloseOperation%28int%29
        this.setSize(750, 750); //set the size.
        this.setResizable(true);//resize the frame.
        this.setTitle("Welocme to new world."); //set the Title.
        ImageIcon imageIcon = new ImageIcon("logo.png");
        this.setIconImage(imageIcon.getImage());
        this.getContentPane().setBackground(new Color(217, 217, 217));
        this.setBackground(Color.YELLOW);//this.setVisible(true);//Make the frame visible.
    }}



import javax.swing.*;
import java.awt.*;
public class MyPanel extends JPanel {
    MyPanel() {
        this.setBackground(Color.white);
        this.setBounds(2,2,25,25);
    }}



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

public class MyLabel extends JLabel {
    MyLabel(){
        this.setText("<html>Heaven <br/>Heaven's body\"<br/>  Whirl around me <br/>Make me wonder</html>");
        //,SwingConstants.CENTER);
        //https://stackoverflow.com/questions/1090098/newline-in-jlabel
        //How to print multi line in java
        ImageIcon image = new ImageIcon("Cosmogony_Björk_Cover.jpg");
        this.setIcon(image);
    //jLabel.setForeground(new Color(217,217,217));
        this.setForeground(Color.BLACK);
        this.setFont(new Font("helvetica",Font.PLAIN,18));
        this.setBackground(Color.gray);
        this.setOpaque(true);
    //jLabel.setVerticalTextPosition(JLabel.TOP); Set the relative text position of the label.
    //jLabel.setBorder();
        this.setVerticalAlignment(JLabel.CENTER);
        this.setHorizontalAlignment(JLabel.CENTER);
}}
jian
  • 4,119
  • 1
  • 17
  • 32

1 Answers1

0

The default Layout Manager of JFrame is the BorderLayout.

Since you did not change the layout manager of your JFrame this is also the current layout manager used in your snippet.

Usually, when using the BorderLayout, you specify which area of the BorderLayout should be populated when adding a component. This is usually done via

frame.add(component, BorderLayout.CENTER);

Notice the area specification in the add() method, which tells the BorderLayout where to place the component.

Here is the issue however. If you use the add() method in combination with the BorderLayout without specifying the placement of the component, it will always place the component in BorderLayout.CENTER. (Causing the component which is currently there to be replaced)

To work around this, do one of the following things:

  • Specify the placement explicitly, so both components will show up:

    frame.add(component1, BorderLayout.PAGE_START);
    frame.add(component2, BorderLayout.CENTER);
    
  • Or use a different Layout Manager, which will take care of the placement for you. E.g. FlowLayout

    JPanel contentPanel = new JPanel(); // JPanel uses flowlayout by default!
    contentPanel.add(component1);
    contentPanel.add(component2);
    myFrame.setContentPane(contentPanel);
    

    You could also explicitly set the layout:

    Container contentPane = myFrame.getContentPane();
    // creates new FlowLayout and sets on content pane
    contentPane.setLayout(new FlowLayout());
    contentPane.add(component1);
    contentPane.add(component2);
    

Sidenotes:

  • Look through the Laying out components within a container Oracle tutorial, which will give you more information on which layout managers there are and how to work with them.

  • When building your GUI, setVisible() on the JFrame should be the last thing you are doing after adding all components. Because if you add components after setting the frame visible, the changes will not immediately take effect without you telling swing that something changed.

  • When correctly working with the Swing Layout Managers, there should be no need to use things like setBounds(...) or setSize(). After adding all components, calling pack() on the JFrame is the preferred way to go. This will size the JFrame according to the preferred size of the components inside.

maloomeister
  • 2,461
  • 1
  • 12
  • 21