سؤال

لتبسيط الأمر، يوجد تطبيق Java Swing بسيط يتكون من JFrame مع بعض المكونات فيه.أحد المكونات هو JPanel الذي من المفترض أن يتم استبداله بـ JPanel آخر عند إجراء المستخدم.

إذن، ما هي الطريقة الصحيحة لفعل مثل هذا الشيء؟لقد حاولت

panel = new CustomJPanelWithComponentsOnIt();
parentFrameJPanelBelongsTo.pack();

ولكن هذا لن ينجح.ما اقتراحك؟

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

المحلول

وحالة استخدامك، يبدو مثاليا ل CardLayout .

في تخطيط بطاقة يمكنك إضافة لوحات متعددة في نفس المكان، ولكن بعد ذلك إظهار أو إخفاء، لوحة واحدة في وقت واحد.

نصائح أخرى

1) وضع لوحة الأول:

JFrame frame=new JFrame();
frame.getContentPane().add(new JPanel());

2) استبدال لوحة:

frame.getContentPane().removeAll();
frame.getContentPane().add(new JPanel());

لاحظ أيضا أنه يجب القيام بذلك في الحدث والموضوع، لضمان ذلك استخدام في SwingUtilities.invokeLater أو في SwingWorker

frame.setContentPane(newContents());
frame.revalidate(); // frame.pack() if you want to resize.

وتذكر، جافا استخدام 'المرجعية نسخة من حيث القيمة حجة عابرة. حتى تغيير متغير تغيير نسخ متعود للإشارة تمريرها إلى أساليب أخرى.

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

وهذا الأمل قطعة من رمز تعطيك فكرة تغيير jPanels داخل JFrame.

public class PanelTest extends JFrame {

        Container contentPane;

        public PanelTest()  {
           super("Changing JPanel inside a JFrame");
           contentPane=getContentPane();
        }

        public void createChangePanel() {
           contentPane.removeAll();
           JPanel newPanel=new JPanel();
           contentPane.add(newPanel);
           System.out.println("new panel created");//for debugging purposes
           validate();
           setVisible(true);
        }
}

في العمل المستخدم:

و// عليك أن تفعل شيئا على غرار

myJFrame.getContentPane().removeAll()
myJFrame.getContentPane().invalidate()

myJFrame.getContentPane().add(newContentPanel)
myJFrame.getContentPane().revalidate()

وبعد ذلك يمكنك تغيير حجم wndow حسب الحاجة.

وكل هذا يتوقف على كيفية الذهاب لاستخدامها. إذا كنت تريد أن الانتقال ذهابا وإيابا بين هذه اللوحات اثنين ثم استخدام CardLayout. إذا كنت تقوم بالتبديل فقط من أول لمرة واحدة والثانية (وليس عودة الى الوراء) ثم أود أن استخدام telcontar الصورة اقتراح وعادل يحل محله. على الرغم من حالة JPanel ليست هي الشيء الوحيد في الإطار الخاص بك وأود أن استخدام إزالة (جافا .awt.Component) بدلا من ذلك من removeAll.

إذا كنت في مكان ما بين هاتين الحالتين لها أساسا المقايضة الوقت في الفضاء. سوف CardLayout توفر لك الوقت ولكن تناول المزيد من الذاكرة من خلال وجود للحفاظ على هذه اللوحة الأخرى كلها في الذاكرة في كافة الأوقات. ولكن إذا كنت مجرد استبدال لوحة عند الحاجة وبناء على الطلب، لم يكن لديك للحفاظ على هذا meory حول لكنه يأخذ مزيدا من الوقت للتبديل.

وأيضا يمكنك محاولة JTabbedPane إلى استخدام علامات التبويب بدلا من ذلك (لها حتى أسهل من CardLayout لأنه يعالج تبين / إخفاء automitically)

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

مشكلة:لا يظهر المكون الخاص بي بعد إضافته إلى الحاوية.

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

مصدر: http://docs.Oracle.com/javase/tutorial/uiswing/layout/problems.html

كنت أعاني من نفس المشكلة بالضبط!!لا يصدق!!الحل الذي وجدته كان:

  1. إضافة كافة المكونات (JPanels) إلى الحاوية؛
  2. باستخدام طريقة setVisible(false) لجميعهم؛
  3. على إجراء المستخدم ، قم بتعيين SetVisible (صحيح) على اللوحة التي أردت عرضها.
// Hiding all components (JPanels) added to a container (ex: another JPanel)
for (Component component : this.container.getComponents()) {
      component.setVisible(false);
}
// Showing only the selected JPanel, the one user wants to see
panel.setVisible(true);

لا يوجد إعادة التحقق () ولا التحقق من الصحة () ولا حاجة إلى CardLayout.

ووlayout.replace () الإجابة موجود فقط / يعمل على مدير GroupLayout.

وLayoutManagers أخرى (CardLayout، BoxLayout الخ) لا تدعم هذه الميزة، ولكن تتطلب منك RemoveLayoutComponent أولا (ثم AddLayoutComponent (مرة أخرى. :-) [فقط وضع الأمور في نصابها الصحيح]

وأنا أقترح عليك إضافة كل لوحة في خلق الإطار، ثم تغيير لوحة واضحة من خلال الدعوة setVisible (صح / خطأ) على حد سواء. عندما يدعو setVisible، وسيتم إخطار ولي الأمر وطلب منه إعادة رسم نفسها.

class Frame1 extends javax.swing.JFrame {

    remove(previouspanel); //or getContentPane().removeAll();

    add(newpanel); //or setContentPane(newpanel);

    invalidate(); validate(); // or ((JComponent) getContentPane()).revalidate();

    repaint(); //DO NOT FORGET REPAINT

}

في بعض الأحيان يمكنك القيام بالعمل دون استخدام إعادة التصديق وأحيانا دون استخدام استخدام repaint.My المشورة على حد سواء.

فقط اتصل بالطريقة علية() بعد ضبط ContentPane, (java 1.7, وربما أكبر سناً) مثل هذا:

JFrame frame = new JFrame();  
JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 
....
frame.setContentPane(panel1);
frame.pack();
...

frame.setContentPane(panel2);
frame.pack();
...

ويمكنك استخدام استبدال طريقة تخطيط:

layout.replace(existingComponent, newComponent)

ومكونات القائمة والجديدة يمكن أن يكون JPanels أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top