【问题标题】:How to use code from one class in another? (Java)如何在另一个类中使用一个类的代码? (爪哇)
【发布时间】:2015-07-17 17:56:33
【问题描述】:

我正在制作坦克游戏,为了避免冗余,我正在制作扩展课程。 我的 MenuPanel 看起来像这个 atm (我只写了对问题很重要的代码) (knop = 荷兰语表示按钮)

public class MenuPanel extends JPanel implements ActionListener
{

    private JButton playKnop, highScoreKnop, quitKnop, HTPKnop;
    private ImageIcon play, HS, quit, HTP;
    private Tanks mainVenster;

    public MenuPanel(Tanks mainVenster) 
    {
        this.mainVenster = mainVenster;
        this.setLayout(null); 

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


        play = new ImageIcon(PlayPanel.class.getResource(/buttons/PLAY.png));
        playKnop = new JButton(play);
        playKnop.setBounds(x, y, width, height);
        playKnop.addActionListener(this);

        HS = new ImageIcon(PlayPanel.class.getResource(/buttons/HS.png));
        highScoreKnop = new JButton(HS);
        highScoreKnop.setBounds(x, 460, width, height);
        highScoreKnop.addActionListener(this);

        HTP = new ImageIcon(PlayPanel.class.getResource(/buttons/HTP.png));
        HTPKnop = new JButton(HTP);
        HTPKnop.setBounds(x, 515, width, height);
        HTPKnop.addActionListener(this);

        quit = new ImageIcon(PlayPanel.class.getResource(/buttons/QUIT.png));
        quitKnop = new JButton(quit);
        quitKnop.setBounds(x, 570, width, height);
        quitKnop.addActionListener(this);

        this.add(playKnop);
        this.add(quitKnop);
        this.add(HTPKnop);
        this.add(highScoreKnop);

        validate();
    }
}

因为制作按钮的代码完全一样(除了背景路径和y坐标)我做了一个类按钮:

package menu;

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

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class button 
{


    public JButton button;
    public ImageIcon buttonImage;

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

    public String backgroundPath;
    public int y;



    public button(String backgroundPath, int y)
    {
        this.backgroundPath = backgroundPath;
        this.y = y;

        buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
        button = new JButton();
        button.setBounds(x, y, width, height);;
        button.addActionListener(this); 
    }



}

这样,我的 menuPanel 可能如下所示:

    package menu;

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

    private button playKnop, highScoreKnop, quitKnop, HTPKnop;
    private JTextField naam;
    private Tanks mainVenster;



    public MenuPanel(Tanks mainVenster) 
    {
        this.mainVenster = mainVenster;
        this.setLayout(null);       

        playKnop = new button("/buttons/PLAY.png", 350);        
        highScoreKnop = new button("/buttons/HS.png", 460);
        quitKnop = new button("/buttons/QUIT.png", 515);
        HTPKnop = new button("/buttons/HTP.png", 570);


        this.add(playKnop);
        this.add(quitKnop);
        this.add(HTPKnop);
        this.add(highScoreKnop);


        validate();

    }


}

我不知道为什么,但是当我这样做时,按钮不会出现,尽管按钮类中的代码是正确的(bc 当我在 menuPanel 本身中使用代码时它可以工作)

我不知道如何解决这个问题,而且我在整个 JavaProject 中有多个类似的问题,但如果有人能解释我如何解决这个问题,我可以摆脱我项目中的所有冗余。

提前致谢, 萝拉

非常感谢大家!您的答案组合帮助我让按钮出现,但由于某种原因,图像没有加载它们。我的代码现在看起来像:

公共类 MenuPanel 扩展 JPanel 实现 ActionListener {

private Button playKnop, highScoreKnop, quitKnop, HTPKnop;

private Tanks mainVenster;

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

public MenuPanel(Tanks mainVenster) 
{
    this.mainVenster = mainVenster;
    this.setLayout(null);

    playKnop = new Button("/buttons/PLAY.png", 350, this);      
    highScoreKnop = new Button("/buttons/HS.png", 460, this);
    quitKnop = new Button("/buttons/QUIT.png", 515, this);
    HTPKnop = new Button("/buttons/HTP.png", 570, this);

    this.add(playKnop);
    this.add(quitKnop);
    this.add(HTPKnop);
    this.add(highScoreKnop);

    validate();

}

public class Button extends JButton
{
    JButton button;
    ImageIcon buttonImage;

    String backgroundPath;
    int y;


    public Button(String backgroundPath, int y, MenuPanel menuPanel)
    {
        super();
        this.backgroundPath = backgroundPath;
        this.y = y;

        buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
        this.setBounds(x, y, width, height);;
        this.addActionListener(menuPanel); 
    }
}

}

(所有按钮都可以工作!)

【问题讨论】:

    标签: java redundancy extending


    【解决方案1】:

    首先,所有的类名都应该以大写字母开头作为约定,这不影响编译,但是很好的做法。

    现在,对于您的实际问题,对我来说突出的第一件事是您的 Button 类没有扩展任何东西。这对我来说似乎是它没有出现在屏幕上的原因。 我建议让Button 扩展JButton

    public class Button extends JButton {
    // Implementation Code
    }
    

    这类似于您的 MenuPanel 扩展 JPanel 的方式。 JPanel 无法呈现您编写的自定义 Button。通过扩展JButton,它将能够渲染它,因为它知道如何与JButton进行交互

    【讨论】:

      【解决方案2】:

      我认为您最好让您的 Button 类扩展 JButton。这样您就可以将自己的按钮类添加到菜单面板中。

      public class Button extends JButton
      {
      
      
          public JButton button;
          public ImageIcon buttonImage;
      
          public int x = 95;
          public int width = 200;
          public int height = 50;
      
          public String backgroundPath;
          public int y;
      
      
      
          public Button(String backgroundPath, int y, MenuPanel menuPanel)
          {
              super()
              this.backgroundPath = backgroundPath;
              this.y = y;
      
              buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
              this.setBounds(x, y, width, height);;
              this.addActionListener(menuPanel); 
          }
      
      
      
      }
      

      【讨论】:

        【解决方案3】:

        你能观察一下这行的区别吗:

        playKnop.addActionListener(this);
        

        以及后面代码中的那个:

        playKnop = new button("/buttons/PLAY.png", 350);  
        

        我相信您想添加 MenuPanel 作为动作侦听器,但您没有在以后的代码中传递对它的引用。你应该有: playKnop = new button("/buttons/PLAY.png", 350, this);

        然后在 Button 类中设置此引用,例如:

        public button(String backgroundPath, int y, MenuPanel menuPanel)
            {
                this.backgroundPath = backgroundPath;
                this.y = y;
        
                buttonImage = new ImageIcon(PlayPanel.class.getResource(backgroundPath));
                button = new JButton();
                button.setBounds(x, y, width, height);;
                button.addActionListener(menuPanel); 
            }
        

        【讨论】:

        • 当您传递this 时,您实际上传递了对该类实例的引用,在您的情况下为MenuPanel。顺便问一下,它解决了你的问题吗?
        • 是的,非常感谢,我收到的答案对我帮助很大。一切正常,但我有最后一个问题。我想使用这个代码是多个面板,所以我需要在构造函数中为MenuPanel menuPanel 提供一个参数。你知道我可以使用哪个参数吗?我的意思是不同的面板,例如“HighscorePanel”“PlayPanel”“HowToPlayPanel”“QuitPanel”......
        【解决方案4】:

        不同之处在于您不再将 JButton 添加到 JPanel。

        要使此代码正常工作,您的“按钮”类必须扩展 JPanel。

        另一种提取共享代码的方法是创建一个“按钮创建方法”而不是一个类,例如:

        public class MenuPanel extends JPanel implements ActionListener
        {
            int y = 95, width = 200, height = 50;
            private JButton playKnop, highScoreKnop, quitKnop, HTPKnop;
        
            public MenuPanel()
            {
                this.setLayout(null);
        
                playKnop = createButton("/buttons/PLAY.png", 350);
                highScoreKnop = createButton("/buttons/HS.png", 460);
                quitKnop = createButton("/buttons/QUIT.png", 515);
                HTPKnop = createButton("/buttons/HTP.png", 570);
        
                this.add(playKnop);
                this.add(quitKnop);
                this.add(HTPKnop);
                this.add(highScoreKnop);
        
                validate();
            }
        
            private JButton createButton(String path, int x) {
                ImageIcon icon = new ImageIcon(MenuPanel.class.getResource(path));
                JButton button = new JButton(icon);
                button.setBounds(x, y, width, height);
                button.addActionListener(this);
                return button;
            }
        
            @Override
            public void actionPerformed(ActionEvent e) {
            }
        }
        

        【讨论】:

          【解决方案5】:

          在现有的MenuPanel,当你这样做

          this.add(playKnop);
          

          您正在将JButton 添加到您的JPanel

          在新的MenuPanel 中,您正在将button 添加到您的JPanel

          您需要将JButton 添加到JPanel

          对于类名,还要选择Button 而不是button

          解决方案是重写此代码,以便将JButtons 而不是buttons 添加到面板中。代码也可能存在其他问题。

          【讨论】:

            【解决方案6】:

            尝试在类按钮中添加getButton,返回按钮进行添加

            public JButton getJButton(){
             retun this.button
            }
            

            然后在菜单面板上添加使用这个

            this.add(playKnop.getJButton());
            

            【讨论】:

              【解决方案7】:

              您的代码没有任何问题。我能看到的唯一问题是您的类button 扩展Object 而不是JButton。因此,只需进行以下更改,我觉得它应该可以工作:

              而不是:

              public class button 
              

              public class button extends JButton
              

              【讨论】:

              • 对,这是第一步。但不要忘记更改实施。您可以删除属性“按钮”,然后从 button.setBounds(x, y, width, height); 更改按钮上的所有函数调用; to this.setBounds(x, y, width, height);
              • 亲爱的投票者,您能否评论一下我的答案为什么或在哪里不正确?
              【解决方案8】:

              也许你想让你的按钮类继承 JButton 而不是保留一个按钮字段。这样,您可以将按钮添加到面板中。

              【讨论】:

                【解决方案9】:

                您添加的内容有所不同。在新代码中,您将 button 类的实例添加到 JPanel。在您添加的旧代码中JButtonsbuttons 不能显示,因为它们不是摇摆类,旧的 JButton 可以。

                从 JButton 扩展按钮应该可以解决问题:

                public class button extends JButton {
                
                // public JButton button; // this line is depreceted now
                
                public ImageIcon buttonImage;
                
                ...
                

                另外,了解 Java 中的代码格式和样式。这将帮助您编写更清晰的代码并防止上述混淆。例如。你有一个名为button 的类,其中有一个名为button 的字段和一个名为button 的方法。使用不同的名称,如 Button(类总是大写!)、buttoncreateButton

                【讨论】:

                  【解决方案10】:

                  我对 JButton 类不是很熟悉。您需要将 buttonImage 设置为背景。也许有一些功能,例如:

                  this.setBackground(buttonImage);
                  

                  如果没有这样的功能,你可以在构造函数中设置背景。类似于您上面的示例。你总是创建一个新的按钮:

                  JButton b = new JButton(buttonImage);
                  

                  您可以在自己的构造函数中为 super() 方法提供相同的参数。结果看起来像这样:

                  public class Button extends JButton
                  {
                     String backgroundPath;
                     int y;
                  
                     public Button(String backgroundPath, int y, MenuPanel menuPanel)
                     {
                         super(new ImageIcon(PlayPanel.class.getResource(backgroundPath)));
                         this.backgroundPath = backgroundPath;
                         this.y = y;
                  
                         this.setBounds(x, y, width, height);
                         this.addActionListener(menuPanel); 
                     }
                  }
                  

                  此代码未经测试。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2012-11-19
                    • 1970-01-01
                    • 2018-06-12
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-06-08
                    相关资源
                    最近更新 更多