【问题标题】:Why is only the top-level component rendered?为什么只渲染顶级组件?
【发布时间】:2011-10-28 13:38:21
【问题描述】:

我正在创建一个在我的网站上使用的游戏小程序,我讨厌 Swing 布局/渲染组件的方式。所以我想我可以设置一个安排,让我做事,我喜欢怎么做(手动告诉窗口管理器何时渲染组件以及对布局使用绝对定位)。 这是我的代码 GameApp.java:

import javax.swing.JApplet;

public class GameApp extends JApplet {

    private Background background;
    private Foreground foreground;

    @Override
    public void init() {
        background = new Background();
        foreground = new Foreground();
    }

    @Override
    public void start() {
        background.render(this);
        foreground.render(this);
    }
}

Foreground.java:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;

public class Foreground extends UIElement {

    private String buttonText;
    private JButton startButton;

    @Override
    public void fetchDependencies() throws Exception {
        buttonText = "Play!";
        startButton = new JButton(buttonText);
    }

    @Override
    public void create() {
        setLayout(null);
        startButton.setBounds(350, 260, 100, 30);
        startButton.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }
        });
        add(startButton);
    }
}

Background.java:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;

public class Background extends UIElement {

    private Image backdrop;

    @Override
    public void fetchDependencies() throws Exception {
        backdrop = Toolkit.getDefaultToolkit().getImage(new URL("mywebpage"));
    }

    @Override
    public void create() {
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(backdrop, 0, 0, parent);
    }
}

UIElement.java:

import javax.swing.JApplet;
import javax.swing.JComponent;

public abstract class UIElement extends JComponent {

    protected JApplet parent;

    public UIElement() {
        try {
            fetchDependencies();
        } catch(Exception e) {
            System.err.println(e);
        }
    }

    public abstract void fetchDependencies() throws Exception;
    public abstract void create();

    public void render(JApplet p) {
        addParent(p);
        create();
        p.getContentPane().add(this);
    }

    private void addParent(JApplet ja) {
        parent = ja;
    }
}

当我运行这个小程序时,它只会显示最近添加的 UIElement。这是为什么呢?

【问题讨论】:

    标签: java swing layout-manager japplet


    【解决方案1】:

    顶级容器(如 JApplet、JFrame)使用 BorderLayout。因此,当您将组件添加到小程序的内容窗格时,默认情况下该组件会添加到“CENTER”。所以只显示最后添加的组件,因为所有组件都占用相同的区域。

    我建议您学习如何使用 Swing 作品,不要尝试创建自己的自定义渲染。

    您不能只告诉窗口何时渲染组件。在不同的时候,组件的绘制是在您不知道的情况下自动完成的,这就是 Swing 具有良好定义的绘制机制的原因。

    【讨论】:

    • 嗯,我知道系统重绘和应用程序重绘,而且我知道我对系统重绘无能为力,这很好。我只是希望能够多一点控制视图。所以你怎么看?我也应该取消 JApplet 的布局吗?
    • @Benjamin 我会学习一个LayoutManager,它允许您以您想要的方式放置组件。 NullLayout 在我看来并不是一个真正的选择。您可以查看GridBagLayoutGridLayoutBoxLayout。其他一些可能正是您所需要的。
    • 您应该使用布局管理器。我在您的问题中没有看到任何其他建议。您的问题不是布局管理器。您的问题是您试图将两个组件堆叠在一起,这与处理组件的二维布局而不是 3D 布局的布局管理器无关。也许您需要使用 JLayeredPane 或类似 Background Panel 的东西。
    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    • 2023-02-01
    相关资源
    最近更新 更多