什么决定了Java中的组件可见性?

时间:2015-11-12 17:59:39

标签: java swing user-interface components visibility

我正在编写一个使用JFrame对象和几个JPanel对象的Java GUI程序。 JPanel对象使用paint()和repaint()方法,而一些JPanel对象使用JLabel和JButtons。当我运行程序时,这些不同组件中的一些组件在我希望它们的方式中是不可见的,即看起来有些组件正在隐藏其他组件。

确定程序运行时哪些组件可见?它是否取决于组件添加到顶级容器的顺序,或者每个对象的paint()方法的调用顺序?可以覆盖此默认可见性吗?

编辑:我应该补充一些JPanel(及其组件)相互重叠。

编辑: 这是一个示例程序。什么决定哪些组件在屏幕上可见?例如,当Button2不是时,为什么Button1可见?

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

public class Test1 extends JFrame {

  public Test1() {
    setLayout(null);
    setSize(500, 700);
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    add(new Test2());
    setVisible(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Test1();
      }
    });
  }
}

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

public class Test2 extends JPanel {

  public Test2() {
    setBounds(0, 0, 300, 500);
    setLayout(null);
    add(new Test3());
    add(new Test4());
    setVisible(true);
  }

  public void paint(Graphics g) {
    g.drawRect(0, 0, 250, 450);
  }
}

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

public class Test3 extends JPanel {

  public Test3() {
    setBounds(0, 0, 300, 300);
    setVisible(true);
  }

  public void paint(Graphics g) {
    g.fillRect(40, 50, 200, 150);
  }
}

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

public class Test4 extends JPanel {

  public JLabel label1 = new JLabel("Label1");
  public JLabel label2 = new JLabel("Label2");

  public JButton button1 = new JButton("Button1");
  public JButton button2 = new JButton("Button2");

  public Test4() {
    setBounds(0, 300, 300, 200);

    add(label1);
    add(label2);
    add(button1);
    add(button2);

    setVisible(true);
  }
}

1 个答案:

答案 0 :(得分:5)

  

我应该补充一些JPanel(及其组件)相互重叠。

ZOrder控制组件的绘制顺序。首先绘制具有较高ZOrder的组件。

  

是否取决于组件添加到顶级容器的顺序

是的,ZOrder被指定为一个组件被添加到Container中,因此最后添加的组件将被绘制。

您可以使用setComponentZOrder(...)类的Container方法手动更改ZOrder(以及绘画顺序)。例如,如果拖动组件并将其绘制在顶部,则应将其ZOrder设置为0。

您可能想查看Overlap Layout。它允许您控制组件在重叠时的显示方式(尽管确实使所有组件的大小相同)

  

这是一个示例程序。

你永远不应该写这样的应用程序,因为你会遇到各种各样的问题:

  1. 不要使用null布局管理器。
  2. 不要覆盖paint()。通过重写paintComponent()并确保调用super.paintComponent(...)来完成自定义绘制。
  3. 不要将面板堆叠在一起。 JPanel是不透明的,因此在彼此之上添加组件将隐藏下面的组件。
  4.   

    当Button2不是时,为什么Button1可见?

    Button1被绘制,因为它具有焦点。如果您将鼠标移到button2旁边,它也会被绘制,因为它会响应mouseOver事件。

    如果你调整框架的大小,两个按钮都会消失,因为面板将根据ZOrder重新绘制。

    我真的不知道你要用这​​个代码做什么。我所能说的就是不要这样做。使用布局管理器。