【问题标题】:Trouble with borders边界问题
【发布时间】:2015-02-04 06:21:53
【问题描述】:

我试图澄清边框的工作原理,特别是插图,在搜索 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. 从 x = 10 和 y = 10 开始绘制一个矩形 (200 x 200)

所以我的问题是 shadowPane 如何超出 JFrame 的范围?边框是在 JFrame 之外 10 像素还是存在于 JFrame 内。从我发现的所有内容来看,它应该在里面,但是根据这段代码如何在框架后面生成阴影,这没有任何意义。任何人都可以帮我完成这个吗?谢谢。

【问题讨论】:

    标签: java swing


    【解决方案1】:

    所以我的问题是 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);
    

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

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

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

    你可以看到还是一样...

    那么发生了什么?

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

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

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

    【讨论】:

    • 1+ 表示“幻觉”。不要使用透明的框架背景,而是尝试使用“Color.RED”,也许它会变得更清楚绘画是如何完成的。
    • 这是一个很棒的解释。我想我错过了这样一个事实,即您可以在另一个 JPanel 之上添加一个 JPanel(我必须研究 JFrame.setContentPane()JPanel.add() 之间的区别)。不过,还有一个更快速的问题,JPanels 的大小是否只能与它们所连接的 Frame 的尺寸相同(显然要减去边框和其他东西......)?我问是因为当我添加panel.setSize(50, 50) 行时,它并没有变小。我只是添加这一行来更好地了解正在发生的事情,所以我不需要解决方案或任何东西。再次感谢!
    • 对不起,我还应该提到我删除了 pack() 并用 frame.setSize(200, 200) 替换它,以便您测试我的想法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-23
    • 2011-03-21
    相关资源
    最近更新 更多