边界麻烦

use*_*170 3 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();
    }
}
}
Run Code Online (Sandbox Code Playgroud)

我解释它的方式是发生的事情:

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

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

Mad*_*mer 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);
Run Code Online (Sandbox Code Playgroud)

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

阴影

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

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

阴影

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

发生什么了?

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

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

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