2011-10-28 124 views
1

我正在创建一个在我的网站上使用的游戏小程序,我讨厌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; 
    } 
} 

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

回答

4

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

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

你不能只告诉窗口何时渲染组件。有一个组件的绘画有不同的时间自动完成,你不知道它是什么,这就是为什么Swing有一个明确的绘制机制。

+0

那么我知道系统重新绘制和应用程序重绘,我知道我不能做任何有关系统重新绘制,这很好。我只是希望能够更多地控制视图。所以你怎么看?我应该清空JApplet的布局? – Benjamin

+1

@Benjamin我会学习一个'LayoutManager',它允许你按照你想要的方式放置组件。在我看来,'NullLayout'并不是真正的选择。你可以看看'GridBagLayout','GridLayout'和'BoxLayout'。其他一些存在,可能正是你所需要的。 – Laf

+0

您应该使用布局管理器。我没有看到你的问题中会有其他建议。你的问题不是布局经理。你的问题是你试图将两个组件叠加在一起,这与处理组件二维布局的布局管理器无关,而不是3D布局。也许你需要使用JLayeredPane或者像[Background Panel](http://tips4java.wordpress.com/2008/10/12/background-panel/)。 – camickr