边界麻烦

时间:2015-02-04 06:21:54

标签: java swing

我试图澄清边界是如何工作的,特别是插图,以及在搜索Java文档和众多网站时,我似乎无法找到明确的解释。看看这段代码:

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class ShadowWindow {

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

public ShadowWindow() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setUndecorated(true);
            frame.setBackground(new Color(0, 0, 0, 0));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setContentPane(new ShadowPane());

            JPanel panel = new JPanel(new GridBagLayout());
            panel.add(new JLabel("Look ma, no hands"));

            frame.add(panel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class ShadowPane extends JPanel {

    public ShadowPane() {
        setLayout(new BorderLayout());
        setOpaque(false);
        setBackground(Color.BLACK);
        setBorder(new EmptyBorder(0, 0, 10, 10));
    }

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

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
        g2d.fillRect(10, 10, getWidth(), getHeight());
        g2d.dispose();
    }
}
}

我解释它的方式就是这样:

  1. 创建JFrame框架(200 x 200)
  2. 创建了JPanel shadowPane(也是200 x 200),在JPanel的内侧底部和右侧内侧创建了一个10像素的空边框
  3. 创建第二个JPanel(200 x 200)并添加到shadowPane
  4. 之上
  5. 从x = 10和y = 10
  6. 开始绘制矩形(200×200)

    所以我的问题是shadowPane如何超越JFrame的范围?边框是在JFrame外部10个像素还是在JFrame内部存在。从我发现它应该在里面的一切,但根据这个代码如何在框架后面产生阴影,这没有意义。任何人都可以带我走过这个?感谢。

1 个答案:

答案 0 :(得分:5)

  

所以我的问题是shadowPane如何超越JFrame的范围?

不是。 pack确定内容的首选布局大小,并使窗口足够大以容纳它,因为框架未涂层并且它的背景是透明的,它“看起来”就像阴影悬挂在框架上一样,这是一种错觉

空边框确保添加到ShadowPane的内容被“强制”进入一个小空间。

让我们稍微改变一下代码......

JFrame frame = new JFrame("Testing");
JPanel content = new JPanel(new BorderLayout());
content.setBackground(Color.RED);
//frame.setUndecorated(true);
//frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(content);
//frame.setContentPane(new ShadowPane());

JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));

ShadowPane shadowPane = new ShadowPane();
shadowPane.add(panel);

frame.add(shadowPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);

这样做,是创建一个新的背景面板,填充红色。它还添加了窗口装饰。

Shadow

如您所见,阴影窗格和标签都在窗口的范围内呈现。

如果我们再次移除窗户装饰......

Shadow

你可以看到它仍然是一样的......

那是怎么回事?

getPreferredSize提供有关组件尺寸的核心信息(在本例中为200x200

EmptyBorder定义了ShadowPane中的可用空间,该空间定义了可以显示内容的区域,它在组件的右侧和底部留下10个像素,其中组件可以'显示。这由布局管理器自动处理。这意味着ShadowPane实际上可以在这里绘制,但是添加到它的组件将永远不会显示在此处,因此是阴影板。

基本上,它是烟雾和镜子,用于在添加到帧中的内容(或者在这种情况下为ShadowPane)后面产生阴影的幻觉