2011-10-28 122 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