2015-11-08 156 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

相关问题