0

This is my code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.TextField;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

class NorthPanel extends JPanel{
    public NorthPanel() { 
        this.setBackground(Color.LIGHT_GRAY); // 배경색 설정
        this.add(new JButton("열기"));
        this.add(new JButton("닫기"));
        this.add(new JButton("나가기"));
    }
}

class CenterPanel extends JPanel{
    public CenterPanel() {
        setLayout(null); // Layout없애줌.(default=bodrderlayout)
        for (int i=0; i<10; i++) {
            int x = (int)(Math.random()*400); // 랜덤 x좌표 생성
            int y = (int)(Math.random()*400); // 랜덤 y좌표 생성
            JLabel l = new JLabel("*");
            l.setForeground(Color.RED);
            l.setLocation(x,y); // 생성한 랜덤좌표로 설정
            l.setSize(20,20);
            add(l);
        }
    }
}

class SouthPanel extends JPanel{
    public SouthPanel() {
        this.setBackground(Color.YELLOW);
        add(new JButton("Word Input"));
        add(new TextField(20));
    }
}
                
public class Panels extends JFrame {
    
    public Panels(){
        this.setTitle("여러 개의 패널을 가진 프레임");
        this.setSize(500,500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 창 닫으면 종료되도록
        Container c = this.getContentPane(); // 기반이 될 contentpane
        c.add(new NorthPanel(), BorderLayout.NORTH);
        c.add(new CenterPanel(), BorderLayout.CENTER);
        c.add(new SouthPanel(), BorderLayout.SOUTH);
        
        this.setVisible(true); // 화면에 보이게
    }
    
    public static void main(String[] args) {
        new Panels();
    }

}

I want to print random "*" in CenterPanel.

JFrame is fluid so I have to get size of NorthPanel, SouthPanel and ContentPane but I don't know how..

How do I get the location of the CenterPanel?

int x = (int)(Math.random()*400);
int y = (int)(Math.random()*400);

400 is temporary integer so I tried getWidth() but that doesn't work.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
yuseon-Lim
  • 29
  • 4
  • Might be a little beyond your needs, but you could do something like this [for example](https://stackoverflow.com/questions/27974966/moving-jpasswordfield-to-absolute-position/27975101#27975101) – MadProgrammer Nov 03 '20 at 03:21
  • There is no good case here for extending panels (`JPanel`) or the window (`JFrame`). Just use instances of each. If you need to reorganize or break up the creation of the different panels or window, put that logic into a method that creates, configures (Adds things to) and returns the component of interest. – Andrew Thompson Nov 03 '20 at 03:59
  • 1
    `setLayout(null); // Layout없애줌.(default=bodrderlayout)` That line of code is wrong for two reasons. 1) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 2) The default layout of a `JPanel` is `FlowLayout`, not `BorderLayout`. – Andrew Thompson Nov 03 '20 at 04:01

1 Answers1

0

First of all, don't use TextField. That is an AWT component. For Swing you should be using JTextField.

Swing components don't have a size until the frame is made visible.

Swing components are responsible for determining their own size. If you want to do custom painting or add random components then you should be overriding the getPreferredSize() method of your component to return its desired size.

@Override
public Dimension getPreferredSize()
{
    return new Dimension(400, 400);
}

Then your constructor can invoke the getPreferredSize() method to get the width/height to be used in your random code.

int x = (int)(Math.random() * getPreferredSize().width); // 랜덤 x좌표 생성
int y = (int)(Math.random() * getPreferredSize().height); // 랜덤 y좌표 생성

Then before you make the frame visible you invoke pack() on the frame and all components will be displayed at their preferred size.

this.pack();
this.setVisible(true); 

Note, why are you trying to display a label at a random position. I also agree with ControlAltDel's answer that custom painting is a better approach (than using label components). However, the same suggestion I made here would apply there as well. That is you would implement getPreferredSize() and use pack().

If you want to use custom painting, then you would create an ArrayList of object to paint. Then the paintComponent() method would iterate through the ArrayList to paint each object. See: Custom Painting Approaches for an example of this approach.

camickr
  • 321,443
  • 19
  • 166
  • 288