سؤال

g'day كل شيء،

أنا ترميز القائمة الرئيسية لمشروع. تعرض القائمة بشكل صحيح. لقد قمت أيضا بإعداد ActionListeners للأزرار الثلاثة في القائمة.

ما أود القيام به هو إعادة استخدام JPanel لمجموعة جديدة من أزرار الراديو عندما يختار المستخدم "بدء لعبة جديدة".

ومع ذلك، فإن الترميز ActionPerformed لإزالة المكونات الموجودة من JPanel قد حظي. أعلم أن Removeall مهم بطريقة أو بأخرى، لكن لسوء الحظ أن Netbeans يعلمني أنني لا أستطيع الاتصال به على كائن Mainmenu JPanel ضمن actionperformed. لذلك علقت بها في التعليمات البرمجية أدناه، لكنني تركها حتى تتمكن من رؤية ما أحاول القيام به.

أفكارك أو تلميحاتك هي موضع تقدير.

هنا هو رمزي الرئيسي:

public class Main {

    public static void main(String[] args) {
        MainMenu menu = new MainMenu();
        menu.pack();
        menu.setVisible(true);
    }
}

هنا رمز Mainmenu الخاص بي:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

    public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");

        public MainMenu() {
            super("RPG Main Menu");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel mainMenu = new JPanel();
            mainMenu.setLayout(new FlowLayout());
            startNewGame.setMnemonic('n');
            loadOldGame.setMnemonic('l');
            seeInstructions.setMnemonic('i');
            startNewGame.addActionListener(this);
            loadOldGame.addActionListener(this);
            seeInstructions.addActionListener(this);
            mainMenu.add(startNewGame);
            mainMenu.add(loadOldGame);
            mainMenu.add(seeInstructions);
            setContentPane(mainMenu);

        }

        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == startNewGame) {
                // StartNewGame code goes here
                // mainMenu.removeAll();
            }
            if (source == loadOldGame) {
                // LoadOldGame code goes here
            }
            if (source == seeInstructions) {
                // Quit code goes here
            }
        }
    }
هل كانت مفيدة؟

المحلول

تحتاج mainmenu لتكون متغير عضو:

 public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");
        JPanel mainMenu = new JPanel();

لماذا تشعر بالحاجة لإعادة استخدام هذا الكائن؟

نصائح أخرى

النظر في استخدام أ CardLayout بدلا من ذلك، الذي يدير مكونين أو أكثر (عادة JPanel مثيلات) التي تشترك في نفس مساحة العرض. بهذه الطريقة لا تضطر إلى كمان إضافة مكونات وإزالةها في وقت التشغيل.

ليس لديك إشارة إلى استخدام Mainmenu ActionPerformed. إذا كنت تعلن Mainmenu مع الأزرار. سوف تعمل.

المشكلة هي أن actionPerformed الطريقة تحاول الاتصال JPanel mainMenu وهو خارج النطاق، أي mainMenu المتغير غير مرئي من actionPerformed طريقة.

طريقة واحدة للتحصل حول هذا هو أن يكون JPanel mainMenu الإعلان في الفصل نفسه وجعله حقل مثيل يمكن الوصول إليه لجميع أساليب مثيل الفصل.

علي سبيل المثال:

public class MainMenu extends JFrame implements ActionListener
{
    ...
    JPanel mainMenu;

    public MainMenu()
    {
        ...
        mainMenu = new JPanel();
        ...
    }

    public void actionPerformed(ActionEvent e)
    {
        ...
        mainMenu.removeAll();
    }
}

تجنب محاولة "إعادة استخدام" الأشياء. أجهزة الكمبيوتر قادرة جدا على الترتيب. التركيز على جعل لك رمز واضح.

لذلك بدلا من محاولة ترتيب اللوحة، ما عليك سوى استبداله بحقيق جديد.

عموما طريقة أفضل لكتابة المستمعين هي دروس داخلية مجهولة. سيكون للرمز داخل هذه الوصول إلى المتغيرات النهائية في النطاق المرفق وأعضاء الطبقة المرفوعة. لذلك، إذا قمت بها mainMenu النهائي وأنت ActionListenerالفصول الداخلية المجهولة المجهولة، يجب أن تجميع التعليمات البرمجية على الأقل.

أيضا لا تحاول "إعادة استخدام" الفصول الدراسية. حاول أن تجعل كل فئة أي شيء واحد معقول، وتجنب الميراث (التنفيذ). لا يوجد أي حاجة لأي حاجة تقريبا JFrame, ، لذلك لا تفعل ذلك. يخترع ActionListener لكل إجراء، بدلا من محاولة تحديد مصدر الحدث.

لاحظ أيضا، يجب عليك دائما استخدام مكونات التأرجح على مؤشر ترابط إرسال الأحداث AWT. غير ال main طريقة لإضافة غنيمة شيء مثل:

public static void main(final String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
        runEDT();
    }});
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top