سؤال

أنا بصدد إنشاء واجهة مستخدم رسومية في Netbeans 6.1 لمشروع التصميم الأول الخاص بي، ولكنني واجهت مشكلة مزعجة.النوافذ المؤقتة مثل PopUp لتسجيل الدخول الخاص بي وغيرها لن تختفي عندما أخبرها.لقد كنت أبحث عن كيفية حل هذه المشكلة لمدة شهرين تقريبًا.لقد قمت بإنشاء موضوع منفصل لـ Pop Up الخاص بي ولكنه لا يزال غير فعال.... الطريقة الوحيدة التي ستختفي بها إذا لم أعبث حرفيًا بأي من مكونات واجهة المستخدم الرسومية الأخرى.... يجب أن يساعد نموذج التعليمات البرمجية الخاص بي في وصف الغضب...لا تمانع في كود الظل، لقد كان لأغراض الاختبار، والذي من الواضح أنه لم يساعد.

//This method is called once a user presses the "first" login button on the main GUI
public synchronized void loginPopUpThread() {
    doHelloWorld = new Thread(){
        @Override
        public synchronized void run()
        {
            try
            {
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(true);
                    System.out.println("waitin");
                    doHelloWorld.wait();
                    System.out.println("Not Sleepin..");
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(false);
            }
            catch (InterruptedException e)
            {
            }
        }
    };
    doHelloWorld.start();

//This is called when the "second" loginB is pressed and the password is correct...
public synchronized void notifyPopUp() {
    synchronized(doHelloWorld) {

        doHelloWorld.notifyAll();
        System.out.println("Notified");
    }
}

لقد قمت أيضًا بتجربة Swing Utilities ولكن ربما قمت بتنفيذها بطريقة خاطئة لأنها المرة الأولى التي أستخدمها فيها.إنه يفعل نفس الشيء مثل الكود أعلاه باستثناء أن النافذة تتجمد عند الانتظار، وهو ما لا يفعله الكود أعلاه:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public synchronized void run() {
            try
            {
                    loginPopUpFrame.pack();
                    loginPopUpFrame.setVisible(true);
                    System.out.println("waitin");
                    wait();
                        System.out.println("Not Sleepin.");
                        loginPopUpFrame.pack();
                       loginPopUpFrame.setVisible(false);
            }
            catch (InterruptedException e)
            {
            }
        }
    });

الرجاء مساعدتي!!!

هل كانت مفيدة؟

المحلول

من البديهيات:

  • لا تتعامل مع مكونات واجهة المستخدم الرسومية في سلاسل رسائل عشوائية؛قم دائمًا بالترتيب للتعامل معها في سلسلة الأحداث
  • لا تنتظر أبدًا أو تنام داخل سلسلة الأحداث (لذلك، لا يتم إرسال التعليمات البرمجية إلى invocLater() أبدًا)

لذا فإن الإجابة على كيفية حل هذه المشكلة هي "بطريقة أخرى"...

ابتعد عن المشكلة قليلاً ما الذي تحاول فعله فعلاً؟ إذا كنت تريد فقط أن ينتظر مربع حوار تسجيل الدخول حتى يقوم المستخدم بإدخال اسم المستخدم وكلمة المرور، فهل هناك سبب لعدم استخدام JDialog المشروط فقط (بعد كل شيء، هذا هو الغرض من ذلك...).

إذا كنت تريد حقًا أن ينتظر بعض الخيط التعسفي إشارة لإغلاق النافذة/التعامل مع واجهة المستخدم الرسومية، فأنت بحاجة للقيام بالانتظار في الموضوع الآخر, ، ومن ثم جعل الذي - التي استدعاء مؤشر الترابط SwingUtilities.invocLater() باستخدام كود معالجة واجهة المستخدم الرسومية الفعلي.

ملاحظة.توجد بالفعل بعض طرق معالجة واجهة المستخدم الرسومية التي يمكن استدعاؤها بشكل آمن من سلاسل رسائل أخرى، على سبيل المثال.غالبًا ما تكون المكالمات التي "تقوم فقط بتعيين تصنيف" آمنة.لكن ما هي المكالمات الآمنة ليست محددة بشكل جيد، لذا من الأفضل تجنب المشكلة عمليًا.

نصائح أخرى

وينبغي ألا يتم التلاعب مكونات سوينغ من موضوع ارسال الحدث البديل.

وSwingUtilites فئة لديها وسائل لتقديم المهام إلى موضوع الإرسال.

ومن الصعب تشخيص مشكلتك. لست متأكدا ما نحاول القيام به مع في انتظر طرق ، ولكن أوصي ترك <لأ href = "http://java.sun.com/javase/6/docs/api/java/lang/Object.html#wait ( ) "يختلط =" نوفولو noreferrer "> انتظر / <لأ href =" http://java.sun.com/javase/6/docs/api/java/lang/Object.html#notify () " يختلط = "نوفولو noreferrer"> إعلام وحدها.

وهذا الرمز له إطارين - عند إنشاء الإطار الثاني، يتم إخفاء أولا حتى تقوم بإغلاقه

.
public class SwapFrames {

  private JFrame frame;

  private JFrame createMainFrame() {
    JButton openOtherFrameButton = new JButton(
        "Show other frame");

    frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new FlowLayout());
    contentPane.add(openOtherFrameButton);
    frame.pack();

    openOtherFrameButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            onClickOpenOtherFrame();
          }
        });

    return frame;
  }

  private void onClickOpenOtherFrame() {
    frame.setVisible(false);

    JFrame otherFrame = new JFrame();
    otherFrame
        .setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    otherFrame.setContentPane(new JLabel(
        "Close this to make other frame reappear."));
    otherFrame.pack();
    otherFrame.setVisible(true);
    otherFrame.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosed(WindowEvent e) {
        frame.setVisible(true);
      }
    });
  }

  public static void main(String[] args) {
    JFrame frame = new SwapFrames().createMainFrame();
    frame.setVisible(true);
  }

}

ولأنني لا أرى أي أدلة منها في التعليمات البرمجية، انا ذاهب الى أقترح عليك <وأ href = "http://java.sun.com/docs/books/tutorial/uiswing/events/index هتمل "يختلط =" نوفولو noreferrer "> تقرأ على استخدام المستمعين الحدث بدلا من محاولة" الانتظار "لرمز لإنهاء.

وليس من الواضح تماما ما كنت تحاول تحقيق، ولكن هل يمكن أن يكون أفضل حالا مع حوار مشروط:

public class DialogDemo {

  public JFrame createApplicationFrame() {
    JButton openDialogButton = new JButton("Open Dialog");

    final JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container container = frame.getContentPane();
    container.setLayout(new FlowLayout());
    container.add(openDialogButton);
    frame.pack();

    openDialogButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            onOpenDialog(frame);
          }
        });

    return frame;
  }

  private void onOpenDialog(JFrame frame) {
    JDialog dialog = createDialog(frame);
    dialog.setVisible(true);
  }

  private JDialog createDialog(JFrame parent) {
    JButton closeDialogButton = new JButton("Close");

    boolean modal = true;
    final JDialog dialog = new JDialog(parent, modal);
    dialog
        .setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    Container container = dialog.getContentPane();
    container.add(closeDialogButton);
    dialog.pack();
    dialog.setLocationRelativeTo(parent);

    closeDialogButton
        .addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            dialog.setVisible(false);
          }
        });

    return dialog;
  }

  public static void main(String[] args) {
    new DialogDemo().createApplicationFrame().setVisible(
        true);
  }

}

وماذا عن القيام ببساطة:

//This method is called once a user presses the "first" login button on the main GUI
public void loginPopUpThread() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            loginPopUpFrame.pack();
            loginPopUpFrame.setVisible(true);
        }
    };
}

//This is called when the "second" loginB is pressed and the password is correct...
public void notifyPopUp() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            loginPopUpFrame.setVisible(false);
        }
    };
}

وماذا كنت تريد حقا أن استخدام غير مشروط JDialog.

ملحوظة، يتم ترك أجزاء من ذلك. انها بك الواجبات المنزلية / المشاريع.

public void actionPerformed(ActionEvent e)
{
   // User clicked the login button
   SwingUtilities.invokeLater(new Runnable()
   {
       public void run()
       {
         LoginDialog ld = new LoginDialog();
         // Will block
         ld.setVisible(true);
       }
   });
}

public class LoginDialog extends JDialog
{
    public LoginDialog()
    {
        super((Frame)null, "Login Dialog", true);

        // create buttons/labels/components, add listeners, etc
    }

    public void actionPerformed(ActionEvent e)
    {
       // user probably clicked login
       // valid their info
       if(validUser)
       {
          // This will release the modality of the JDialog and free up the rest of the app
          setVisible(false);
          dispose();
       }
       else
       {
          // bad user ! scold them angrily, a frowny face will do
       }
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top