صعوبة في إزالة جميع المكونات من JPanel
-
05-09-2019 - |
سؤال
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();
}});
}