2015-11-08 155 views
0

我搜索了一下,發現一些類似的問題,但沒有適用於我的情況,所以我在這裏。有沒有辦法從ouside的類中繪製JPanel對象?

我試圖做一個不同層次的遊戲,每個層次都完全不同。

最初,我的代碼看起來像這樣和精細的工作:

public class Life extends JPanel{ 

private Story story; 

public Life(){ 
    story = new Story(this); 

} 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    story.render(g) 

public void terminate(){ 
    story.terminate(); 
    System.out.println("Terminated"); 
} 

public static void main(String[] args){ 
    final JFrame frame = new JFrame("Life"); 
    final Life life = new Life(); 
    frame.add(life); 
} 
} 



public class Story { 

private int phase; 
private Life life; 


public Story(Life life){ 
    this.life = life; 
    phase = 0; 
} 

public void render(Graphics g){ 
    if(phase == 0) levelOneRender(g); 
    if(phase == 1) levelTwoRender(g); 
} 
} 

我很擔心我會浪費時間每場比賽蜱檢查我是在什麼階段由於我打算有20+階段。 ,代碼會很快效率低下。

所以我有一個想法,我生命中的對象一起從JPanel的圖形對象簡單地傳遞給我的故事對象和油漆的JPanel在不同的類這樣的每一個階段:

public class Life extends JPanel{ 

public Life(){ 

    story = new Story(this); 
} 


public static void main(String[] args){ 
    final JFrame frame = new JFrame("Life"); 
    final Life life = new Life(); 

} 

} 


public class Story { 

private int phase; 
private Intro intro; 
private Life life; 


public Story(Life life){ 
    this.life = life; 
    phase = 0; 
    intro = new Intro(this); 
} 

public void nextPhase(){ 
    this.phase++; 
} 


public Life getLife() { 
    return this.life; 
} 
} 

public class Intro { 

private static final int DELAY = 100; // in milliseconds, so 10 ticks per second 

private Timer timer; 
private Story story; 
private Graphics g; 
private int counter; 


public Intro(Story story) { 
    this.story = story; 
    this.g = story.getLife().getGraphics(); 
    this.counter = 0; 

    timer = new Timer(DELAY, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      tick(); 
      story.repaint(); 
     } 
    }); 
    timer.start(); 
} 

public void tick(){ 
    if(counter <= 40){ 
     terminate(); 
    } 
    counter++; 
    render(); 
} 

public void render(){ 
    story.getLife().paint(g); 
    Graphics2D g2 = (Graphics2D)g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

    g2.draw(new Rectangle(0,0,10,10)); 


} 

public void terminate(){ 
    timer.stop(); 
    story.nextPhase(); 
} 
} 

可惜,這只是does not work,as story.getLife()。paint(g);在類Intro引發nullPointerException時,當我運行它。而且我很確定這不是我嘗試的唯一問題。

有沒有正確的方法去做我要做的事?

非常感謝您的時間。任何洞察力將不勝感激。

+0

您可以創建另一個具有'paint(Graphics g)'方法的類,然後在面板的paintComponent方法中調用該方法(您在擴展'JPanel'的類中覆蓋的方法):'myPainter.paint(g) ;'。然後,您可以在您創建的新類中處理繪畫 –

+0

最初我使用了paintComponent,但它是一種受保護的方法,因此我無法引用它。油漆是公開的,並且看起來很相似,所以我嘗試了它,並且失敗了。這不是一個壞主意,它會解決這個錯誤,但它與我的第一個代碼有什麼不同? – KingTheoden

+0

你不應該自己調用'paint'或'paintComponent'。 Swing渲染系統調用它們。至於差別,沒有。甚至沒有看到tbh:s但是你的問題很容易解決。創建'Level'對象,然後有一個'Level Level;'字段變量。將它的值切換到切換級別。我會發佈一個答案 –

回答

1
public void render(Graphics g){ 
    if(phase == 0) levelOneRender(g); 
    if(phase == 1) levelTwoRender(g); 
} 

這不像你想象的那麼大。你現在擁有的是好的。但是這些檢查可以避免(如您所要求的)。

而不是處理在不同的方法每個級別的繪畫,處理它們在不同的對象:

public bstract class Level { 
    public abstract void paint(Graphics g); 
} 

public final class LevelOne extends Level { 
    public void paint(Graphics g) { 
     //... 
    } 
} 

public final class LevelTwo extends Level { 
    public void paint(Graphics g) { 
     //... 
    } 
} 

這種方式,而不是檢查的int值,看畫,其渲染,你可以切換Level值呈現一個新的水平:

Level one = new LevelOne(); 
Level two = new LevelTwo(); 

Level currentLevel = one; 

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 

    currentLevel.paint(g); 
} 

簡單地切換的level值來呈現不同程度的

+0

感謝您的洞察力,我試圖做的是讓Story Extension JFrame,並且每個單獨的級別類擴展JPanel,並添加和刪除框架中的面板。 – KingTheoden

+0

故事[不是]](https://en.m.wikipedia.org/wiki/Is-a)'JFrame'(如'Dog'是'Animal'),所以它不應該擴展它。而不是添加/刪除,你想使用'CardLayout'來切換面板。儘管'Level'不是'JPanel',('JPanel'只是一個繪圖區域/組件容器)。你的'Level'可以[有](https://en.m.wikipedia.org/wiki/Has-a)'LevelPanel'。也許有一個LevelContainer(控制器),它有一個Level(模型)和一個LevelPanel(視圖)。查看MadProgrammer的評論獲取更多信息 –

+0

嗯,你提出了一個很好的觀點。好的,我會修復以同意這些想法。 – KingTheoden

相關問題