Наследование JButton Java - проблема переопределения метода - PullRequest
0 голосов
/ 01 марта 2020

Я хочу установить видимость 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);   

    }
}

Ответы [ 2 ]

1 голос
/ 01 марта 2020

Когда вы заставили AccountTemplate расширить класс HW, каждый метод, который был переопределен в AccountTemplate, переопределял исходный метод из HW. GetWriteBtnVisibility проверяется изнутри метода инициализации HW, но метод инициализации AccountTemplate переопределяет его. Теперь StudentAccount наследует переопределенный метод, который не проверяет логическое значение getWriteBtnVisibility, поэтому видимость не изменяется.

Если я правильно понимаю, вы пытаетесь расширить компоновку с использованием наследования, однако для этого что вам нужно создать отдельные методы, которые создают и инициализируют компоненты интерфейса и вызывают их по мере необходимости из класса. Теперь вы создали только отдельный метод для имени кнопки и видимости, но метод, который проверяет логическое значение видимости, был переопределен и больше не вызывается.

Вам придется изменить архитектуру так, чтобы:

  • Существует только одно поле JFrame (если вам не нужно несколько интерфейсов)
  • Существует только один метод, который создает JFrame и устанавливает заголовок
  • Все общие c Компоненты интерфейса создаются с использованием отдельного (окончательного) метода и могут вызываться по требованию класса, который его наследует.

Простой пример

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 может также выбрать, какие компоненты использовать и инициализировать, а какие - какие ему не нужны, и затем он может добавить свои собственные компоненты во фрейм.

0 голосов
/ 01 марта 2020

Важный метод инициализации, который устанавливает видимость кнопки, - это тот, который вызывается из класса HW, и этот метод вызывается только из ActionListener кнопки AccountTemplate здесь:

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

Обратите внимание, что это это вызов метода HW main, и поэтому это происходит при создании экземпляра HW, когда это происходит (поскольку именно это создает main HW), а не экземпляра StudentAccount. Вот почему ваше наследование не работает - при создании кнопки наследование не происходит.

Сказав это, я должен сказать, что этот код слишком сложен, гораздо больше, чем нужно и злоупотребляет наследованием таким образом, что только запутывает. Не используйте наследование (или абсолютное расположение и нулевые макеты), поскольку вы просто без необходимости усложняете вещи. Просто ваш код, и вы будете мне благодарны.

Если бы это был мой проект,

  • Я бы создал отдельные JPanels (не JFrames) для каждого типа GUI
  • Я бы использовал наследование только для модели программы, логических не GUI аспектов кода, а не для представлений (GUI классы), и использовал бы это очень осторожно.
  • Я бы поменял местами представления с помощью CardLayout , а не поменял местами JFrames
...