簡體   English   中英

JButton Java 的繼承 - 覆蓋方法問題

[英]Inheritence of a JButton Java - Overriding Method Issue

我想在另一個類中將 JButton 的可見性設置為 false。 所以我正在做的是覆蓋我在StudentAccount創建的名為getWriteBtnVisibility()的布爾函數,以更改HW類中按鈕的可見性。 所以基本上我想讓 JButton 在StudentAccount不可見。 因為我希望該按鈕在登錄不同類型的帳戶時可見。但是,我這樣做的方式似乎不起作用。 我已經調試了我的代碼,但不明白為什么它沒有覆蓋函數 如果我能得到一些指導,我將不勝感激。

StudentAccount

import java.awt.EventQueue;


public class StudentAccount extends AccountTemplate {


    /**
     * Launch the application.
     */


    @Override
    public String getHomeworkBtnName() {
        return "Submit Assignment";
    }

    @Override
    public boolean getWriteBtnVisibility() {
        return false;
    }




    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    StudentAccount window = new StudentAccount();
                    window.frmAccountTemplate.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

AccountTemplate

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class AccountTemplate extends HW {

    protected JFrame frmAccountTemplate;

    /**
     * Launch the application.
     */
    public String getHomeworkBtnName() {
        return "Hw";
    }


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    AccountTemplate window = new AccountTemplate();
                    window.frmAccountTemplate.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public AccountTemplate() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    protected void initialize() {
        frmAccountTemplate = new JFrame();
        frmAccountTemplate.setTitle(getFrameTitleName());
        frmAccountTemplate.setBounds(100, 100, 450, 300);
        frmAccountTemplate.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmAccountTemplate.getContentPane().setLayout(null);

        JButton btnAssignment = new JButton(getHomeworkBtnName());
        btnAssignment.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                frmAccountTemplate.dispose();

                HW.main(null);
            }
        });

        btnAssignment.setFont(new Font("Tahoma", Font.BOLD, 16));
        btnAssignment.setBounds(15, 51, 200, 29);
        frmAccountTemplate.getContentPane().add(btnAssignment);



    }

}

HW

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.filechooser.FileSystemView;

import javax.swing.JButton;
import javax.swing.JFileChooser;

import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.awt.event.ActionEvent;

public class HW {

    public JFrame frmHw;

    /**
     * Launch the application.
     */
    public boolean getWriteBtnVisibility() {
        return true;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    HW window = new HW();
                    window.frmHw.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public HW() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    protected void initialize() {
        frmHw = new JFrame();
        frmHw.setTitle("HW");
        frmHw.setBounds(100, 100, 450, 300);
        frmHw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmHw.getContentPane().setLayout(null);

        JTextArea jTextArea1 = new JTextArea();
        jTextArea1.setBounds(9, 11, 328, 197);
        frmHw.getContentPane().add(jTextArea1);

        JScrollPane scrollBar = new JScrollPane(jTextArea1);
        scrollBar.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        scrollBar.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        frmHw.getContentPane().add(scrollBar);
        scrollBar.setBounds(13, 39, 413, 189);


        JButton btnWriteText = new JButton("Write Text");
        btnWriteText.setVisible(getWriteBtnVisibility());
        btnWriteText.setBounds(154, 11, 115, 24);
        frmHw.getContentPane().add(btnWriteText);   

    }
}

當您使 AccountTemplate 擴展 HW 類時,AccountTemplate 中重新定義的每個方法都會覆蓋 HW 中的原始方法。 getWriteBtnVisibility 從硬件的 initialize 方法中檢查,但 AccountTemplate 的 initialize 方法覆蓋它。 現在 StudentAccount 繼承了不檢查 getWriteBtnVisibility 布爾值的重寫方法,因此不修改可見性。

如果我正確理解您想要做的是使用繼承擴展布局,但是要做到這一點,您需要創建單獨的方法來創建和初始化界面組件並根據需要從類中調用它們。 現在您只為按鈕名稱和可見性創建了一個單獨的方法,但檢查可見性布爾值的方法已被覆蓋,不再被調用。

您將不得不重新設計您的架構,以便:

  • 只有一個 JFrame 字段(除非你想要多個接口)
  • 只有一種方法可以創建 JFrame 並設置標題
  • 所有通用接口組件都是使用單獨的(final)方法創建的,並且可以在繼承它的類需要時調用

一個簡單的例子

class HW {
  public JFrame frame;

  public String getFrameName() {
    return "HW";
  }

  public boolean getHWBtnVisibility {return true;}

  void setupHWComponents() {
    JTextField field = new JTextField();
    // ...
    this.frame.getContentPane().add(field);

    JButton button = new JButton("HW");
    button.setVisible(getHWBtnVisibility());
    // ...
   }


  void initFrame() {
    this.frame = new JFrame(getFrameName());
    // ....
   }

  void initialize() {
    initFrame();
    setupHWComponents();
  }
}

class AccountTemplate {
   public void setupTemplateComponents() {
     JTextField loginField = new JTextField("login");
     super.frame.getContentPane().add(loginField);
     // ...
    }

   @Override
   public void initialize() {
     // Setup Frame and HW components
     // If you dont want HW components, replace with initFrame()
     super.initialize(); 
     setupTemplateComponents();
   }
}

然后 StudentAccount 類同樣可以選擇要使用和初始化的組件以及它不需要的組件,然后它可以將自己的組件添加到框架中。

重要的 initialize 方法設置按鈕的可見性是從 HW 類調用的方法,並且該方法僅在 AccountTemplate 按鈕的 ActionListener 中調用:

public void actionPerformed(ActionEvent e) {
    frmAccountTemplate.dispose();
    HW.main(null);
}

請注意,這是對HW main 方法的調用,因此發生這種情況時正在創建的是一個 HW 實例(因為這是 HW main 創建的),而不是 StudentAccount 實例。 這就是您的繼承不起作用的原因——創建按鈕時沒有發生繼承。

話雖如此,我必須聲明這段代碼過於復雜,遠遠超出了它的需要,並且以一種只會混淆的方式濫用了繼承。 不要使用繼承(或絕對定位和空布局),因為你只是不必要地使事情復雜化。 只需您的代碼,您就會感謝我。

如果這是我的項目

  • 我會為每種類型的 GUI 創建不同的 JPanels(不是 JFrames)
  • 我只會將繼承用於程序模型、代碼的邏輯非 GUI 方面,而不用於視圖(GUI 類),並且會非常謹慎地使用它。
  • 我會使用CardLayout交換視圖而不是交換 JFrames

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM