الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

فشلت في إظهار مجسمات JLabel بالشكل الصحيح في حلقة الfor وحتى الwhile

بدأه W.B في 5 أبريل 2010 · 22 رد · 1,297 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم !

رسالة إلى المشرفين الأعزاء في أسفل هذا الموضوع !

# معطيات المشكلة :

- لدي مصفوفة
ثنائية الأبعاد
تتكون من عدد من الأحجار -
Block(
Point
,
String
)
- ، أسميت هذه
المصفوفة
باسم
blocks
، تعبر النقطة هنا عن موقع الجسم ويعبر النص عن قيمة مفتاح لصورة هذا الحجر

- لدي
HashMap<
String
,
String
>
باسم
imgs
، وهو يربط بين مفتاح نصي ورابط لملف صورة

- لدي دالة باسم
putBlock(
Block
)
، وهي تهتم بعرض الحجر في واجهة البرنامج أمام المستخدم

- المشكلة متكونة في دالة باسم
setGameContents()
، وهي تهتم بعرض جميع الأحجار الموجودة في المصفوفة blocks أمام الستختدم وبالإضافة إلى عرض خلفية لواجهة البرنامج

- المشكلة متكونة في class
مشتق
من
JFrame

# توضيح للمعطيات ببعض الأكواد :

blocks = new Block[][]{{new Block(Point,String)}};


JLabel label = new JLabel(new ImageIcon(imgs.get(block.getValue())));

label.setLocation((int)block.getHead().getX(),(int)block.getHead().getY()); // Block.getHead(): Point , وهو موقع مقدمة الحجر

abel.setSize(block.getWidth(), block.getHeight());

// Block.getWidth(): int , وهو قيمة العرض للحجر , Block.getHeight(): int , وهو قيمة الطول للحجر


add(label);

}
void putBlock(Block block){


ImageIcon backgroundImg = new ImageIcon(imgs.get("background"));

JLabel backgroundLabel = new JLabel(backgroundImg);


Block testBlock = new Block(15,115,"b"); // أنشأت حجر للتجربة

// التجربة هنا تتم بالنتيجة المطلوبة (الموقع صحيح + يظهر أمام خلفية البرنامج)

putBlock(testBlock);


for(int y = 0 ; y < rows ; y++)

for(int x = 0 ; x < columns ; x++)

// العملية هنا تتم بنتيجة شبه سيئة (الموقع دائماً في منتصف واجهة البرنامج + لا يظهر أمام خلفية البرنامج وإنما يستتر خلفها)

putBlock(blocks[y][x]);


getContentPane().add(backgroundLabel);

pack();

}
void setGameContents(){

# النتيجة المطلوبة :

عرض جميع هذه الكائنات من المصفوفة blocks أمام خلفية البرنامج وفي المكان الصحيح

# النتيجة الحالية :

الكائنات المنشأة في حلقة الـfor تكون
مستترة خلف خلفية البرنامج وتقع دائماً في المنتصف
، أما بالنسبة للجسم testBlock المنشأ خارج الحلقة فنتيجته سليمة

إلى المشرفين /

أعتذر :

- إن كان مكان هذا الموضوع ليس في القسم المناسب !

- إن كانت المشكلة أو الاستفسار لا يستحق عرضه في موضوع مستقل !

تم تعديل هذه المشاركة بواسطة W.B في 5 أبريل 2010 في 18:19

#2

لماذا لا تضيف الخلفية أولاً؟

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#3

علاء الصالحي كتب:

لماذا لا تضيف الخلفية أولاً؟

تحياتي

أضفت الخلفية في مقدمة الدالة ..

فاختفت المجسمات
-التي وضعتها للتجربة-
أيضاً !

أعني أني نقلت
هذا الكود
إلى أعلى الدالة :


pack();
getContentPane().add(backgroundLabel);

#4

هناك موضوع هنا في المنتدى عن الخلفية ابحث عنه لا أذكر عنه سوى أنه للأخت بنت اليمن

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#5

بإذن الله سأبحث بعد قليل ..

فقد يفيدني في إظهار المجسمات أعلى الخلفية !

لكن هل سيفيدني في
السيطرة على أماكن المجسمات
فلا أدري ولا أظن وسأجرب ! :-)
-المجسمات كانت ترتكز سابقاً في منتصف الواجهة وتستتر خلف الخلفية-

شاكر لك أستاذ علاء مقدماً !

#6

لو تضع الكود كاملا حتى نستطيع التجربة

#7
اقتباس

لو تضع الكود كاملا حتى نستطيع التجربة

أنا كنت سأقترح نفس الشيء

لولا أني قدرت أن الموضوع له علاقة بالجامعة أو ما شابه

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#8

أعتقد أنك لم تضبط الـ LayoutManager الخاص بالحاوية التي تضيف عليها الـ"أحجار". عليك بضبطه إلى null وبذلك تضمن إمكانية تحريكه يدوياً إلى أي نقطة تحددها.

أما إن لم تكن ترغب في تداخل الأحجار فوق بعضها أبداً فأقترح عليك استخدام GridLayout

إن لم تكن تعرف ما هي الـ LayoutManagers ابحث بالمنتدى هناك معلومات جيدة عنهم.

احتمال آخر وارد:

أرى أنك أنشأت حجر التجربة كما يلي:

Block testBlock = new Block(15,115,"b");

أي أنك قمت بضبط موضعه

لكني لا أرى كيف أنشأت عناصر المصفوفة blocks

هل قمت بضبط مواضع كل عناصرها ؟

#9

إذا لم تغير ال layout manager فهذا يعني أنك تستعمل BorderLayout. وعندما تستعمل add دون تحديد المكان، فإنه يستعمل المكان الإفتراضي، أي BorderLayout.CENTER، مما يعني أن كل المكونات ستضاف فوق بعضها البعض في الوسط ولن يظهر إلا المكون الأخير الذي أضيف

أظن أن GridLayout يصلح لما تريد القيام به

#10

أستاذ علاء !

وجدت الموضوع هنا ::..
..:: ..

لكن ولهذه اللحظة لم أستطع الوصول لنتيجة مناسبة ..

ف
أحتاج وقتاً كافياً
للبحث والتوسع عن طريق الوصلات المضافة فيها ..

بالإضافة إلى أني أظن بأني لست في حاجة له (
الآن
) ..

لا سيما وأن صورة الخلفية تعمل حالياً بالكفاءة المطلوبة !
JustPassing كتب:

لو تضع الكود كاملا حتى نستطيع التجربة

أتمنى ذلك .. فأنا وعلى كل حال المسفتيد الأول ! :)

لكن وحتى يستقيم البرنامج وتقوم بتجربته ..

فأنا مضطر لاطلاعك على classes
-التي أجبرت على الاعتماد عليها-
وحقوقها للجامعة
! :(
Speed_Of_Light كتب:

أعتقد أنك لم تضبط الـ LayoutManager الخاص بالحاوية التي تضيف عليها الـ"أحجار". عليك بضبطه إلى null وبذلك تضمن إمكانية تحريكه يدوياً إلى أي نقطة تحددها.

أما إن لم تكن ترغب في تداخل الأحجار فوق بعضها أبداً فأقترح عليك استخدام GridLayout

إن لم تكن تعرف ما هي الـ LayoutManagers ابحث بالمنتدى هناك معلومات جيدة عنهم.

نعم أنا لم أتدخل في LayoutManager !

لكن وبعد تجربة سابقة ..

فـ GridLayout لا يفيدني هنا ..

لا سيما وأن المجسمات تأخذ
أشكالاً متباينة في الأبعاد
..

بالإضافة إلى أن المجسمات
لا تأخذ مواقع منتظمة
فهي هي قابلة للانتشار بشكل عشوائي !
Speed_Of_Light كتب:
احتمال آخر وارد:

أرى أنك أنشأت حجر التجربة كما يلي:

Block testBlock = new Block(15,115,"b");

أي أنك قمت بضبط موضعه

لكني لا أرى كيف أنشأت عناصر المصفوفة blocks

هل قمت بضبط مواضع كل عناصرها ؟

نعم قمت بضبطها !

وتأكدت من ذلك ..

بحيث أن الدالة putBlock تقوم بقراءة كل المعلومات عن كل Block تقوم بالتنفيذ عليه وطبعها في الـconsole ..

وتظهر لي
قيم صحيحة لكل العناصر
سواءاً testBlock أو كل ما يداخل المصفوفة blocks !
JustPassing كتب:

إذا لم تغير ال layout manager فهذا يعني أنك تستعمل BorderLayout. وعندما تستعمل add دون تحديد المكان، فإنه يستعمل المكان الإفتراضي، أي BorderLayout.CENTER، مما يعني أن كل المكونات ستضاف فوق بعضها البعض في الوسط ولن يظهر إلا المكون الأخير الذي أضيف

أظن أن GridLayout يصلح لما تريد القيام به

لا أظن ذلك ..

فالمجسمات هنا
عشوائية الأبعاد وعشوائية المواقع
!

ولهذا فأنا أعتمد يدوياً على تحديد المواقع باستخدام
Component.setLocation(int,int)
..

الذي لم يفلح مع عناصر المصفوفة blocks !

تم تعديل هذه المشاركة بواسطة W.B في 5 أبريل 2010 في 21:56

#11
اقتباس
نعم أنا لم أتدخل في LayoutManager !

إذاً عليك التدخل ! :happy:

قم بضبطه إلى null

بالمناسبة ما نوع الحاوية التي تضيف إليها لصاقات JLable ؟

قم بعمل screenshot وأرنا المشكلة بالضبط

تم تعديل هذه المشاركة بواسطة Speed_Of_Light في 5 أبريل 2010 في 21:54

#12

Speed_Of_Light كتب:

إذاً عليك التدخل ! :happy:

قم بضبطه إلى null

وضعت setLayout(null) ..

فذهبت
صورة الخلفية معه وما خلف الخلفية من مجسمات
وبقي testBlock ! ^^
Speed_Of_Light كتب:
بالمناسبة ما نوع الحاوية التي تضيف إليها لصاقات JLable ؟

إن كنت فهمت المقصود بنوع الحاوية صحيحاً ..

فنوع الحاوية
ImageIcon
..

وإن لم تكن تقصد ذلك ..

فنوع الحاوية هي إحدى بنات العم
JFrame
!
Speed_Of_Light كتب:
قم بعمل screenshot وأرنا المشكلة بالضبط

في المرفقات ..

من
الصورة الأولى
تجد
صورة الخلفية
بلون رمادي غامق ومن أمامه
testBlock
!

ومن
الصورة الثانية
تجد
testBlock
ومن خلفه
آخر عناصر blocks
!

post-127879-12705000034451_thumb.png

post-127879-12705000129548_thumb.png

#13

بعد تجربة ..

لاحظت أن المشكلة تكمن في
المصفوفة نفسها
أعني blocks
!

والسبب هو أني قارنت بين أحد العناصر وبين مجسم له نفس القيم .. والنتيجة false !

التجربة في هذه الكود :


System.out.println(blocks[5][5].equals(new Block(515,515,"b"))); // Console = false
System.out.println(blocks[5][5].toString() + "###" + (new Block(515,515,"b")).toString()); // Console = ( 515.0 , 515.0 ) = b###( 515.0 , 515.0 ) = b

أرجو التوضيح !

بعد التعديل :

المعذرة كانت الدالة toString() لا تغطي جميع معلومات Block ..

وتم التعديل عليها قبل قليل لإظهار قيم النقاط التي يحتويها هذا الـBlock !

نتيجة التجربة الآن :


// result on Console = ( 515.0 , 515.0 ) = b, has these points = {}###( 515.0 , 515.0 ) = b, has these points = {(515,515), (615,515), (715,515)}


ystem.out.println(blocks[5][5].equals(new Block(515,515,"b"))); // result on Console = false
System.out.println(blocks[5][5].toString() + "###" + (new Block(515,515,"b")).toString());

تم تعديل هذه المشاركة بواسطة W.B في 6 أبريل 2010 في 12:32

#14

1- انصحك باستخدام grid layout

2- تأند من انك تعمل initialize for block head and x y

#15

Mohammed Mshari Ersan كتب:

1- انصحك باستخدام grid layout

2- تأند من انك تعمل initialize for block head and x y

1#:
كما أعلم فالـGridLayout
سيجعل المجسمات محاذية لبعضها
!

وهذه النقطة ستفقدني المرونة في نشر المجسمات عشوائياً ..

بالإضافة إلى أن المجسمات ستكون
قابلة للحركة
من قبل المستخدم !

في هذا الرد صورة توضح إحدى الحالات للأماكن الممكنة للمجسمات بالنسبة لشاشة المستخدم ! ::..
..::

2#:
أنا متأكد من إعطائي قيم الإحداثيات لكل مجسم ..

وتأكدت أيضاً من ذلك من خلال طباعة المعلومات عن كل مجسم يمر إلى الدالة putBlock() ..

وهناك ووجدت قيم الإحداثيات صحيحة !

أي أن
setLocation(int,int)
-في تلك الدالة-
ستقوم بوضع كل مجسم في المكان المناسب !

* في المرفق وضعت Block.class

Block.java

تم تعديل هذه المشاركة بواسطة W.B في 6 أبريل 2010 في 13:28

#16

لن أستطيع مساعدتك من دون كود :wacko:

1
#17

بما أنه لا يوجد شيفرة

جرب أن تعيد شرح المشكلة من البداية

وادعم الشرح بالصور

لعل وعسى :)

تحيااتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#18

Speed_Of_Light كتب:

لن أستطيع مساعدتك من دون كود :wacko:

خسارة !

على كلِ أقدر لك مجهودك الذي بذلته !

شكراً لك أستاذي !
:)
علاء الصالحي كتب:

بما أنه لا يوجد شيفرة

جرب أن تعيد شرح المشكلة من البداية

وادعم الشرح بالصور

لعل وعسى :)

تحيااتي

لا بأس بذلك ولا حاجة لاعادة الطرح من جديد ..

فربما كنت كسولآ
لجعلي الآخرين يتحملون أعباء !

والأولى مني الاعتماد على الذات في التعليم !

شاكر لك أستاذي علاء !
:)

ولمن كانت لديه معرفة في مكان مشكلتي ..

فليدلي مشكوراً بما لديه !

:rose:

تم تعديل هذه المشاركة بواسطة W.B في 6 أبريل 2010 في 20:06

#19

كلما تعمقت في حصر المشكلة ..

كلما زادت المشكلة لي غموضاً !

لحد هذه اللحظة ..

وجدت الآتي :

  • - في
    LevelReader
    class هناك دالة اسمها
    getSBlocks()
    ..

    وهذه تعطي مصفوفة نصية ثنائية الأبعاد والتي تعني لي هنا قيم المجسمات
    -لا أعني الإحداثيات-
    !

    - في
    الـclass الحالي
    هناك دالة ت
    هتم فقط بجلب كل ما تنتجه الـLevelReader
    ..

    وأسميت هذه الدالة
    getFromLevelReader()
    !

    وهذا هو الجزء الهم من هذه الدالة :



/*1*/ rows = levelReader.getRows();

/*2*/ columns = levelReader.getColumns();

/*3*/ String[][] sBlocks = levelReader.getSBlocks();

/*4*/ blocks = new Block[rows][columns];

/*5*/ for(int pos = 0 ; pos < rows*columns ; pos++)

/*6*/ if(pos==11)

/*7*/ blocks[1][5] = new Block(MIN_X+WIDTH,MIN_Y+5*HEIGHT,"a");

/*8*/ else

/*9*/ blocks[pos/columns][pos%columns] = new Block(MIN_X+pos/columns*WIDTH,MIN_Y+pos%columns*HEIGHT,sBlocks[pos/columns][pos%columns]);


}
private void getFromLevelReader(){


ركز تحديداً على سطر رقم 3 و9
-فهما المتهمان في تزوير القيم والتلاعب بمأشر الضغط لدي-
..

فكنت وما أزال أراها
-نظرياً-
أوامر صحيحة وأنها ستعطي النتيجة المطلوبة !

(تجاهل في سطر 7 و9 الإحداثيات ومدى صحتها
-فمتأكد أنا من ذلك-
)

- المجسم في الموضع رقم 12
-كما في السطر 7-
يعمل بالشكل المطلوب
-تماماً-
!

- المجسمات فيما دون الموضع رقم 12 يحصل لهم كما طرحت لكم من
مشكلة في الظهور الصحيح
!

بإختصار
..

لم يفلح استدعاء القيم النصية من المصفوفة sBlocks
..

وهنا أسأل عن السبب وعن الحل !

#20

جرب عمل تنقيح Debug للكود لتتأكد أنه يعمل كما تريد

تم تعديل هذه المشاركة بواسطة Speed_Of_Light في 6 أبريل 2010 في 22:31

#21

Speed_Of_Light كتب:

جرب عمل تنقيح Debug للكود لتتأكد أنه يعمل كما تريد

كيف يمكن لي أن أستفيد من الـDebug في حالتي الآن ؟

فكما أعرف ..

أني
لا أستطيع أن أستفيده منه إلا إذا حصل في البرنامج مشكلة كالـSyntax أو ما شابهه !

وفي حالتي هذه لم أستطع أن أجعل الـDebug يظهر لي تتبعه للبرنامج وتنقيحه له ..

ووجدت أن جميع الـThreads في حالة العمل !

أخيراً أنا وضعت عمداً أمر خاطئ في البرنامج ..

وعن طريق الـDebug وجدت أن القيمة النصية لنوع أحد المجسمات
قيمة صحيحة
!

وهذا هو تماماً ما ظهر لي عند استدعائي لـtoString() في الـConsole ..

حيث تظهر لي كل القيم وكأنها صحيحة !

تم تعديل هذه المشاركة بواسطة W.B في 6 أبريل 2010 في 22:59

#22

أي IDE تستخدم ؟

قصدت بالتنقيح عمل نقطة توقف BreakPoint قبل الموضع الذي تشك في وجود الخطأ فيه ثم تنفيذ الكود سطر تلو الآخر مع مراقبة قيم المتحولاتز

#23

Speed_Of_Light كتب:

أي IDE تستخدم ؟

قصدت بالتنقيح عمل نقطة توقف BreakPoint قبل الموضع الذي تشك في وجود الخطأ فيه ثم تنفيذ الكود سطر تلو الآخر مع مراقبة قيم المتحولاتز

آها !

لكن وعلى كل حال ..

ظهرت لي عناصر المصفوفة بالقيم المناسبة وكأن الأمور تسير بالشكل المتوقع !

هل تمانع لو عملت معك موعد في ::..
..::
لترى عملي على الواقع ؟

لا أستطيع إرسال رسالة خاصة !

ولو أني أنوي لغدِ
-بإذن الله-
أطرح مشكلتي على المشرفين في الكلية !

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…