【问题标题】:Why aren't my label and button showing up in my JFrame?为什么我的标签和按钮没有出现在我的 JFrame 中?
【发布时间】:2014-11-08 21:54:24
【问题描述】:

我似乎一辈子都无法弄清楚这一点。如果有多余的代码,请原谅,但我一直在尝试并无法弄清楚。 JFrame 出现,但按钮和标签未出现。

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

public class ex03 {

     int w = 20;
     int h = 20;

     public ex03() {
         JFrame fra = new JFrame("");
         fra.setBounds(10, 10, 200, 200);
         fra.setLayout(null);
         fra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         fra.setVisible(true);

         JPanel pan = new JPanel();
         pan.setLayout(null);
         pan.setVisible(true);
         fra.getContentPane().add(pan);

         JLabel lab = new JLabel();
         lab.setBounds(10, 10, w, h);
         lab.setOpaque(true);
         lab.setBackground(Color.blue);
         lab.setVisible(true);

         JButton but = new JButton("Play");
         but.setBounds(10, 10, 100, 35);
         but.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
                 w++;
                 h++;
             }
         });
         but.setVisible(true);

         pan.add(lab);
         pan.add(but);
     }

     public static void main (String[] args) {
         new ex03();
     }
}

【问题讨论】:

  • fra.setLayout(null) 是您问题的开始。避免使用null 布局,像素完美的布局是现代 ui 设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

标签: java swing user-interface jframe layout-manager


【解决方案1】:

将可见元素添加到内容窗格后,您需要调用fra.setVisible(true);

【讨论】:

    【解决方案2】:

    问题是在顶层容器(窗口)可见之后添加按钮和标签。因此,必须重新验证组件层次结构才能使组件也可见:

    pan.add(lab);
    pan.add(but);
    pan.revalidate();
    pan.repaint();
    

    根据Container#add(Component comp) 文档:

    这个方法改变了布局相关的信息,因此, 使组件层次结构无效。如果容器已经 显示后,必须验证层次结构,以便 显示添加的组件。

    另一方面,更好的做法是在添加所有组件后打包并使窗口可见,因此组件层次结构只验证一次。

    pan.add(lab);
    pan.add(but);
    ...
    frame.add(pan);
    frame.pack();
    frame.setVisible(true);
    

    其他cmets

    请注意,Swing 旨在与Layout Managers 一起使用,因此不鼓励使用setBounds(...)setLocation(...)setXxxSize(...) 等方法。组件的位置和大小是布局管理器的职责,而不是开发人员的职责,除非您有充分的理由这样做。来自Doing Without a Layout Manager (Absolute Positioning) 部分:

    虽然可以不使用布局管理器,但您应该尽可能使用布局管理器。布局管理器使它 更容易调整到依赖外观的组件外观,以 不同的字体大小,容器的变化大小,以及不同的 语言环境。布局管理器也可以很容易地被其他人重用 容器,以及其他程序。

    【讨论】:

    • nb: invalidate, revalidate, validate 都在布局管理器 API 中处理,所以除非他们采纳你的第二条建议,否则调用它们毫无意义...... ;)
    • @MadProgrammer 我不知道。非常感谢你! :)
    • 更新:有趣的事情,它在the docs 中说明并且总是忽略布局管理器推断。 @MadProgrammer
    【解决方案3】:

    使父框架可见和更新子组件图形的组合将起作用:

    fra.setVisible(true);
    progressLabel.update(progressLabel.getGraphics());
    

    【讨论】:

      猜你喜欢
      • 2012-10-20
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-04
      相关资源
      最近更新 更多