2015-05-08 59 views
0

我正在做一个游戏,我正在尝试去掉代码中的所有冗余。我所有的面板(PlayPanel,HighScore,Quit,..)都有很多共同的特性,所以我在所有面板中都制作了IPanel类。它看起来像这样:我可以在另一个类中使用一个类(构造函数+方法)的代码吗? (java)

package menu; 

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

public class IPanel extends JPanel implements ActionListener{ 

    public Image achtergrond; 
    public Tanks mainVenster; 

    public String backgroundPath; 



    public IPanel(String backgroundPath, Tanks mainVenster) 
    {  
     super(); 
     this.mainVenster = mainVenster; 
     this.setLayout(null); 

     this.backgroundPath = backgroundPath; 
     achtergrond = new  //achtergrond is dutch for background 
      ImageIcon(getClass().getResource(backgroundPath)).getImage(); 

    } 

    public void paintComponent(Graphics g) 
    { 
      super.paintComponent(g); 
      g.drawImage(achtergrond, 0, 0, this.getWidth(), this.getHeight(), 
       this); 
    } 


    public void actionPerformed(ActionEvent ae) 
    { 
     mainVenster.switchPanel(); 
    } 

    public void switchPanel(Tanks toActivate) 
    { 
     remove(mainVenster); 
     mainVenster = toActivate; 
     add(mainVenster); //this is wrong, no idea what to do actually 

     validate(); 
     repaint(); 
    } 

    } 

我能使用构造函数在其他类,但我不知道如何使用 paintComponentactionPerformed方法在其他类。我在所有面板中都使用了这两种方法,所以我认为没有必要为所有这些面板重新编写方法。

我的面板之一的一个例子是QuitPanel

package menu; 

import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 



@SuppressWarnings("serial") 
public class QuitPanel extends JPanel implements ActionListener 
{ 

    public Button yesKnop, noKnop; 
    public JLabel label; 
    public Tanks mainVenster; 
    public QuitPanel quitPanel; 

    public IPanel quit; 


    public QuitPanel(Tanks mainVenster) 
    { 

     quit = new IPanel("/achtergronden/menu.jpg", mainVenster); 

     int x = 95, width = 200, height = 50; 

     label = new JLabel("ARE YOU SURE?"); 
     Font font = new Font("Courier", Font.BOLD, 25); 
     label.setFont(font); 
     label.setBounds(x+20, 400, width, height); 

     yesKnop = new Button("/buttons/YES.png",x, 450, this);  
     noKnop = new Button("/buttons/NO.png",x, 525, this); 

     this.add(quit); 
     this.add(label); 
     this.add(noKnop); 
     this.add(yesKnop); 

    } 


    public void actionPerformed(ActionEvent ae) 
    { 
     if(ae.getSource() == noKnop) 
      quit.switchPanel(mainVenster); //this is wrong 
     else if(ae.getSource() == yesKnop) 
      System.exit(0); 

    } 

} 

,你可以看到我扩展了类JPanel,因为当我试图扩大IPanel我得到了在public HTPPanel(Tanks mainVenster)一个错误,说 the error

当我打开我的quitPanel我得到这个: quitPanel when opened

,所以我知道一定有我的代码正确的一部分,唯一的问题是,我背景不加载 - >(public void paintComponent(Graphics g)法)

问题是:我如何使用我在类nr 2中的类nr 1中创建的方法?

此外,noButton不工作(yesButton工作正常) - >(public void actionPerformed(ActionEvent ae)方法) - >也因为public void switchPanel(Tanks toActivate)我猜

太感谢你了!

回答

3

是的,你可以,有两种广义的方法,组成和interhitence。

通过组合,您可以将代码推入您的当前解决方案然后使用的新类,方法是创建并保存代码保存类的实例。

通过继承,您可以创建一个当前解决方案扩展的类,并将代码放入该父类的方法中。然后你有“其他”类扩展包含所需代码的类。

一般来说,构成比继承更容易处理;但随着时间的推移,由于能够利用多态性,您将会意识到何时继承是更好的解决方案。

0

您应该将不带参数的默认构造函数添加到IPanel类,例如

public IPanel() { } 

然后你可以使用你的父类IPanel进行扩展。

+0

这似乎是一个合理的答案,但我真的不明白如何我可以调用构造函数没有我想要的参数... – Lola

1

错误是因为在扩展IPanel时,您至少需要使用super的构造函数中的一个。在这种情况下,有一个,所以你不得不使用:

public IPanel(String backgroundPath, Tanks mainVenster) 

修正

它不一定是你需要到(似乎理想对我来说),但在一个构造函数,其中一个superclass's构造函数需要用super(...)来调用。

意义,如果我有A类的构造函数:

public class A { 
    public A(String name) { 
    } 
} 

B extends A类,我可以做几件事情:

public class B { 
    // Option 1: Superclass's Constructor 
    public B(String name) { 
     super(name); 
    } 

    // Option 2: Pass static value 
    public B() { 
     super("something here"); 
    } 

    // Option 3: Use null 
    public B() { 
     super(null); 
    } 
} 

不管如何,到最后,如果你的superclass只包含constructorsparameters,子类中的每个constructor将需要调用super(...)superclass's constructors之一。

如果您在您的superclass中放置了默认的constructor例如:public A() {},那么您不需要在其中任何一个上调用super()

0

如果指定一个构造函数,编译器不会为您创建没有参数的构造函数(您在IPanel类中执行了此操作)。

public class A { 
    public A(String str) { 
     //Compiler will not create a constructor without parameters. 
    } 
} 

逆转,如果没有指定一个构造函数,编译器会不为你的参数(你在HTPPanel类这样做)创建一个构造函数。

public class A { 
    //Compiler will create a constructor without parameters. 
} 

现在的事情是,在扩展某个其他类的类中,默认构造函数将调用它的超类构造方法,但不带任何参数。

public class A { 
    public A(String str) {} 
} 

public class B extends A {} 

public class C { 
    public static void main(String[] args) { 
     B b = new B(); //Compile error 
    } 
} 

而且,如果你指定的B类构造函数,但它的父类的构造不添加通话时,编译器会自动调用父类的构造不带参数

public class A { 
    public A(String str) {} 
} 

public class B extends A { 
    public B(int i) {} 
} 

public class C { 
    public static void main(String[] args) { 
     B b = new B(); //Compile error 
    } 
} 

换句话说,您应该添加一个构造函数与您茁壮类没有参数,(或加用适当的参数超级构造函数的调用),但我相信这不是你想在这里做什么。

现在,至于你的其他问题,这可能是由于多种原因,它将永远是没有完整代码的猜测。另外考虑一下,当你打算用一些Panel类扩展IPanel类时,如果你想重写这个面板中的paintComponent方法并且仍然绘制背景,你应该调用super.paintComponent(g);,试图找出为什么

相关问题