【问题标题】:Java swing JLabel doesn't appear in BorderLayoutJava swing JLabel 没有出现在 BorderLayout 中
【发布时间】:2021-11-13 08:21:58
【问题描述】:

我在 JPanel 上用随机位置打了 10 颗星。

但问题是当我设置布局时,开始不显示。

public class Main {

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(300, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container c = frame.getContentPane();
    c.setLayout(new BorderLayout());

    JPanel northPanel = new JPanel(new FlowLayout());
    northPanel.add(new JButton("Open"));
    c.add(northPanel, BorderLayout.NORTH);

    JPanel southPanel = new JPanel(new FlowLayout());
    southPanel.add(new JButton("Integer Input"));
    c.add(southPanel, BorderLayout.SOUTH);

    JPanel centerPanel = new JPanel(null);
    centerPanel.setBackground(Color.pink);
    for(int i = 0; i < 10; i++) {
        int x = (int) (Math.random() * 300);
        int y = (int) (Math.random() * 300);
        JLabel label = new JLabel("*");
        label.setLocation(x, y);
        label.setForeground(Color.green);
        label.setOpaque(true);
        centerPanel.add(label);
    }
    c.add(centerPanel, BorderLayout.CENTER);

    frame.setVisible(true);
}

在粉红色部分,应该显示 10 颗星

【问题讨论】:

  • 您已经减轻了布局管理器的角色,但似乎并没有理解他们实际上在做什么。您看不到标签,因为它们必须为实际大小(即默认为 0x0
  • 如果你“绝对”必须直接控制组件的位置,那么我建议是时候构建自己的布局管理器了,for example
  • 如果您想在随机位置放置 10 个“星形”图像(或 *),我建议您通过 custom painting 进行操作。

标签: java swing jlabel layout-manager border-layout


【解决方案1】:

我找到了自己的路。

设置后label.setSize(10,10);

我可以在面板中找到 10 颗星。

【讨论】:

    【解决方案2】:

    如果您想在随机位置放置 10 个字符 (*),我建议您通过自定义绘画来完成,如下面的 mre 所示:

    import java.awt.*;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.*;
    
    public class Main {
    
        public static void main(String[] args) {
    
            JFrame frame = new JFrame();
            //frame.setSize(300, 300); don't set size let the layout managers do it
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Container c = frame.getContentPane();
            //c.setLayout(new BorderLayout()); not needed, it is the default
    
            JPanel northPanel = new JPanel(new FlowLayout()); //FlowLayout is the default
            northPanel.add(new JButton("Open"));
            c.add(northPanel, BorderLayout.NORTH);
    
            JPanel southPanel = new JPanel(new FlowLayout());
            southPanel.add(new JButton("Integer Input"));
            c.add(southPanel, BorderLayout.SOUTH);
    
            JPanel centerPanel = new PinkPlanet();
            c.add(centerPanel, BorderLayout.CENTER);
            frame.pack();
            frame.setVisible(true);
        }
    }
    
    class PinkPlanet extends JPanel{
    
        private static final int W = 300, H = 300;
        private static final String STAR ="*";
        private final Dimension pSize = new Dimension(W, H);
        private final List<Point> locations = new ArrayList<>();
    
        public PinkPlanet() {
            setBackground(Color.pink);
            for(int i = 0; i < 10; i++) {
                int x = (int) (Math.random() * W);
                int y = (int) (Math.random() * H);
                locations.add(new Point(x, y));
            }
        }
    
        @Override
        public Dimension getPreferredSize() {
            return pSize;
        }
    
        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            for(Point location : locations){
                g.drawString(STAR, location.x, location.y);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      Basically, every container like JPanel, JFrame used some layout to place the component in some specific order. as per your code, you are passing null as argument to centralPanel. so basically central panel has no layout to place component.
      Note : Flow Layout is a default layout.
      
      in this case lets try with below steps.
      1. please use setBound(x, y, height, width), on the place of setLocation(x, y).
          for (int i = 0; i < 10; i++) {
               int x = (int) (Math.random() * 300);
               int y = (int) (Math.random() * 300);
               JLabel label = new JLabel("*");
               **label.setBounds(x,y,10,10);**
               label.setForeground(Color.green);
               label.setOpaque(true);
               centerPanel.add(label);
          }
      
      
        [1]: https://i.stack.imgur.com/RUlUI.png
      

      【讨论】:

      • 考虑使用自定义绘画而不是手动设置边界。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-24
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      相关资源
      最近更新 更多