PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : بررسي مدل لايه بندي BoxLayout



TAHA
10-02-2009, 07:27 AM
ديگر از انواع مدلهاي لايه ‌بندي در فريم ‌هاي جاوا، مدل لايه ‌بندي BoxLayout مي ‌باشد. این مدل لایه ‌بندی، يكي از کلاس ‌هاي بسته javax.swing مي‌ ‌باشد. براي شروع كار بهتر است ابتدا برنامه VerticalBox.java را اجرا نموده و خروجي آن را بررسي نماييد. تصوير زير خروجي اين برنامه را نمايش داده است.

http://pnu-club.com/../pic/37-1.JPG



همانطور که می بینید این مدل لایه بندی قادر است کامپوننت ها را در یک ردیف یا یک ستون قرار دهد.
************************************

1. ایجاد لایه بندی BoxLayout
برای ایجاد اين نوع لایه بندی، به صورت زیر عمل می کنیم:

...



JFrame frame = new JFrame("BoxLayout");
container =frame.getContentPane();

BoxLayout boxlayout = new BoxLayout(container, BoxLayout.Y_AXIS);

container.setLayout(boxlayout);
button = new JButton("First");
container.add(button);
button = new JButton("Second");
container.add(button);
button = new JButton("Third");
container.add(button);


...
كد هاي بالا قسمتي از برنامه قبل مي باشد. در اين بخش نحوه لايه بندي از نوع BoxLayout نمايش داده شده است. در تكه برنامه بالا كانتينر بصورتي لايه‌بندي شده است كه كامپوننت ها بصورت عمودي و در يك رديف قرار بگيرند. «تصوير بالا - سمت چپ» حال اگر بخواهيم فرم پس از لايه بندي بصورت تصوير سمت راست شود، بجاي عبارت قرمز رنگ مشخص شده در تكه كد فوق، از عبارت BoxLayout.X_AXIS استفاده مي نماييم.

نکته مهم : اگر بخواهیم کد بالا را به صورت زیر تغییر دهیم، برنامه اجرا نخواهد شد و در خروجی اعلام خطاخواهد کرد:





JFrame frame = new JFrame("BoxLayout");

BoxLayout boxlayout = new BoxLayout( frame , BoxLayout.Y_AXIS);

frame.setLayout(boxlayout);

... Error Message

Exception in thread "main" java.awt.AWTError: BoxLayout can't be shared

at javax.swing.BoxLayout.checkContainer(BoxLayout.jav a:415)

at javax.swing.BoxLayout.invalidateLayout(BoxLayout.j ava:202)

... Error Message

button = new JButton("First");

frame.add(button);




اما چه دلیلی باعث می شود که برنامه اعلام خطا کند؟ همانطور که در قسمت فریم ها (http://pnu-club.com/articles/java%20se/JFrame/Jframe%20structure.htm) گفته شد، کامپوننت ها بطور پيش فرض، درون قاب Content Pane فریم قرار می گیرند. اما در كد بالا، بجاي اينكه کامپوننت ها را درون این قاب (Content Pane) قرار دهیم در فریم اصلیقرار داده ايم که مجاز به انجام این کار نیستیم.
************************************
2. نکاتی در مورد سایز، مکان و Border کامپوننت ها در BoxLayout
وقتی یک BoxLayout، کامپوننت ها را به صورت عمودی یا افقی لایه بندی می کند، کامپوننت ها در سایز عادی خودشان يا Preferred در کانتینر قرار مي‌گیرند. قبل از هرگونه توضيحي، ابتدا برنامه BoxLayout1.java را از انتهاي مقاله دانلود كرده و آن را اجرا نماييد. سپس سعي كنيد تا فرم را تغيير اندازه دهيد. خواهيد ديد كه بجز دكمه دوم، اندازه ساير دكمه ها تغيير نخواهد كرد. تصوير زير خروجي برنامه در حالت پيش فرض و بدون تغيير اندازه فرم مي باشد.


http://pnu-club.com/../pic/37-2.JPG
حال اگر اندازه فرم تغيير كند، خواهيم داشت:

http://pnu-club.com/../pic/37-3.JPG



تکه کد های زیر قسمتی از این برنامه را نشان می دهد:



...

Button2 = new JButton("Button2");
Button2.setAlignmentX(Component.CENTER_ALIGNMENT);
Button2.setMaximumSize(new Dimension(Short.MAX_VALUE,Short.MAX_VALUE));
frame.add(Button2);


System.out.println(Button2.getMinimumSize());
System.out.println(Button2.getMaximumSize());
System.out.println(Button2.getPreferredSize());

Button2.setBorder(BorderFactory.createCompoundBord er(
BorderFactory.createLineBorder(Color.RED),Button2. getBorder()));

Button3 = new JButton("Button3");
Button3.setAlignmentX(Component.CENTER_ALIGNMENT);
Button3.setPreferredSize(new Dimension(Short.SIZE,Short.SIZE));
frame.add(Button3);

...


در عبارت فوق چند نكته مهم وجود دارد:
1- در اين برنامه براي تعيين اندازه كامپوننت ها از سه متد زير استفاده شده است:

1-setMaximumSize 2-setMinimumSize 3-setPreferredSize
متد اول براي تعيين حداكثر و متد دوم جهت تعيين حداقل ابعاد كامپوننت مورد نظر بكار مي رود. اما در متد سوم اندازه كامپوننت توسط مدیریت لایه بندی (Layout Manager) یک کانتینر كه وظيفه ترسیم یک کامپوننت را بر عهده دارد، تعيين مي شود. محاسبه ابعاد كامپوننت در اين روش به عواملی چون سایز فونت داخل کامپوننت ، سایز متن داخل یک کامپوننت ، تصویری که ممکن است درون یک کامپوننت قرار بگیرد، نوع و اندازه Border ي که ممکن است برای یک کامپوننت در نظر گرفته شود و ... بستگی دارد. توجه نماييد كه بهتر است از اين متد براي تعيين ابعاد كامپوننت استفاده شود.

معمولاً به دو روش می توان سایز یک کامپوننت را تغییر داد،
a. در روش اول می توان از متد با الگوی set****Size استفاده کرد:




comp.setMinimumSize(new Dimension(50, 25));

comp.setPreferredSize(new Dimension(50, 25));

comp.setMaximumSize(new Dimension(Short.MAX_VALUE,Short.MAX_VALUE));

b. در روش دوم می توان متد با الگوی get****Size به صورت زیر ابعاد كامپونت را تعيين نمود:

public Dimension getMaximumSize() {

size = getPreferredSize();

size.width = Short.MAX_VALUE;

return size;

}

2- استفاده از کلاس Short:
این کلاس داراي چندین مقدار ثابت مي باشد. از جمله اين ثوابت، دو ثابت MAX_VALUE ،MIN_VALUE مي باشد.
a- مقدار MAX_VALUE يا حداكثر مقدار، ثابتي با ارزش 215-1 مي باشد.
b- مقدار MIN_VALUE يا حداقل مقدار، ثابتي با ارزش 215 - مي باشد.

3- استفاده از سه متد زير براي نمايش ابعاد تعيين شده در هر يك از سه متد توضيح داده شده در مورد شماره يك.


System.out.println(Button2.getMinimumSize());
System.out.println(Button2.getMaximumSize());
System.out.println(Button2.getPreferredSize());
4- کامپوننت هایی که در لایه بندی BoxLayout قرار می گیرند به صورت پیش فرض از چپ به راست قرار می گیرند. برای اینکه بتوان آنها را درمرکز فریم قرار داد، بصورت زير عمل مي نماييم:


Button1.setAlignmentX(Component.CENTER_ALIGNMENT);

علاوه بر آنچه که در آرگمان متد setAlignmentX وجود دارد می توان حالات دیگری هم برای قرار دادن کامپوننت ها درون متد استفاده کرد ، از جمله اين موارد Component.RIGHT_ALIGNMENT، Component.LEFT_ALIGNMENTو... مي باشند.

5- نكته آخر در اين برنامه نحوه تعيين Border مي باشد. براي انجام اين كار از عبارت زير كمك مي گيريم.


Button2.setBorder(BorderFactory.createCompoundBord er(
BorderFactory.createLineBorder(Color.RED),Button2. getBorder())

);
براي كسب اطلاعات بيشتر در مورد تعيين Border ها، مي توانيد مقاله شماره 35 (http://pnu-club.com/articles/java%20se/Swing_Other_Feature/Border.htm) را مطالعه نماييد.

************************************
3. ایجاد فضای خالی میان کامپوننت ها
يكي از نكات مهم در اين مدل لايه بندي آن است كه تمامي كامپوننت هاي موجود در فرم، بدون هيچ فاصله اي در كنار يكديگر قرار مي گيرند. براي رفع اين مشكل بايد به كمك راه كارهايي بين كامپوننت ها، فاصله مورد نياز را ايجاد نماييم.
برای قرار دادن فضای خالي میان کامپوننت ها دو راه وجود دارد:
1- راه اول این است که از Border میان کامپوننت ها استفاده نماییم.
در اين روش به كمك Border هر يك از كامپوننت ها ميزان فضاي خالي مورد نياز را بوجود مي آوريم. شرح دقيق اين موضوع در مقاله شماره 35 (http://pnu-club.com/articles/java%20se/Swing_Other_Feature/Border.htm) آورده شده است. براي درك بهتر اين تكنيك مي توانيد برنامه BoxLayout3.java را بررسي نماييد. تکه کد زیر قسمتي از اين برنامه مي باشد که در آن کامپوننت Button بوسیله استفاده از تکنیک Border، از دو Button دیگر جدا شده است:



...

button = new JButton("First");

button.setAlignmentX(Component.CENTER_ALIGNMENT);

container.add(button);

button = new JButton("Second");

button.setAlignmentX(Component.CENTER_ALIGNMENT);

container.add(button);

Color color = container.getBackground();

button.setBorder(BorderFactory.createCompoundBorde r(

BorderFactory.createMatteBorder(30,30,30,30,color) ,button.getBorder()));

button = new JButton("Third");

button.setAlignmentX(Component.CENTER_ALIGNMENT);

container.add(button);

...

تصوير زير خروجي اين برنامه را نشان مي دهد. همانطور كه در اين تصوير نشان داده شده است مي توانيد علاوه بر ابعاد Border، رنگي را نيز براي آن تعيين نماييد.

http://pnu-club.com/../pic/37-4.JPG

شکل بالا-چپ خروجي اصلي برنامه را نشان مي دهد. در حالی که شکل دیگر برای ملموس تر شدن نتیجه نشان داده شده است. برای ایجاد شکل سمت راست، باید در قطعه کدی که معرفی شد، بجای کلمه color در آرگمان پنجم متد createMatteBorder از واژه Color.BLUE استفاده کنیم.

2- روش دیگر ایجاد فاصله میان کامپوننت ها، استفاده از کامپوننت های نامرئی است.
در این شیوه برای ایجاد فاصله از کلاس Box و زیر کلاس آن با نام Box.Filler بهره می گیریم. Box.Filler کامپوننت شفافی است که رنگ نمی پذیرد و برای ایجاد فاصله بکار می رود. جدول زیر نشان می دهد که این کلاس چگونه کار می کند.


متد
چگونگی ایجاد محدودیت
نوع ایجاد فضا Box.createRigidArea(size) http://pnu-club.com/../pic/37-5.JPG
rigid area
Box.createHorizontalGlue() http://pnu-club.com/../pic/37-6.JPG افقی glue Box.createVerticalGlue() http://pnu-club.com/../pic/37-7.JPG عموی Box.createHorizontalStrut(int width) http://pnu-club.com/../pic/37-8.JPG افقی strut Box.createVerticalStrut(int height) http://pnu-club.com/../pic/37-9.JPG عمودی new Box.Filler(minSize,prefSize,maxSize) همانند قبل
custom Box.Filler



اکنون به بررسی هریک از مدهای بالا می پردازیم:

1- Rigid Area : زمانی از این مدل استفاده می شود که بخواهیم یک سایز fixed میان دو کامپوننت به وجود بیاوریم. این متد در دو جهت پهنا و ارتفاع اقدام به قرار دادن فضای خالی میان کامپوننت ها می کند. همچنین این مدل می تواند برای لایه بندی افقی و عمودی استفاده شود. قطعه کد زیر این کار را انجام می دهد که در این قطعه کد فضایی به اندازه 5 پیکسل میان دو کامپوننت در پهنا قرار می گیرد. در این حالت کامپوننتی هایی در بالا و پایین یکدیگر وجود ندارند پس نیازی هم برای تعیین ارتفاع فضای خالی بالا و پایین کامپوننت ها نخواهیم داشت و مقدار صفر را برای آن در نظر خواهیم گرفت.



container.add(firstComponent);

container.add(Box.createRigidArea(new Dimension(5,0)));

container.add(secondComponent);



http://pnu-club.com/../pic/37-10.JPG

براي درك بهتر اين بخش، برنامه RigidAreaBoxLayout.java را بررسي نماييد. نكته مهم در اين تكنيك آن است كه حتی با تغییر سایز فریم نیز فاصله میان کامپوننت ها fixed است و تغییر نمی کند.

2- Glue : در این شیوه محدودیتی در اینکه دقیقاً چه مقدار فاصله میان کامپوننت ها قرار دهیم نداریم و با تغییر سایز کانتینری که کامپوننت ها درون آن هستند، فاصله میان کامپوننت ها هم تغییر می کند. این مسأله باعث می شود که این شیوه در مقایسه با تكنيك ُStrut و Rigid Area قابل انعطاف پذير باشد. معمولاً توصیه می شود که از HorizontalGlue در لايه بندي افقي و از VerticalGlue در لايه بندي عمودي استفاده شود.


http://pnu-club.com/../pic/37-11.JPG



container.add(firstComponent);

container.add(Box.createHorizontalGlue());

یا

container.add(Box.createVerticalGlue());

container.add(secondComponent);

تصوير زير خروجي برنامه GlueSample.java را نمايش مي دهد. در اين برنامه نحوه پياده سازي اين تكنيك قابل مشاهده مي باشد.


http://pnu-club.com/../pic/37-12.JPG


برنامه HBoxWithGlue.java برنامه ی دیگری است که نحوه استفاده از اين تكنيك را نمايش داده است. تصوير زير خروجي اين برنامه مي باشد.


http://pnu-club.com/../pic/37-13.JPG
3- Strut : این شیوه هم فضای ثابتی برای ایجاد فاصله میان کامپوننت ها ایجاد می کند. نکته مهمی که در این روش وجود دارد این است که باید در یک مدل لایه بندی افقی از HorizontalStrut و در یک لایه بندی عمودی از VerticalStrut استفاده شود زیرا هنگامی که از این مدل در Panel های تو در تو استفاده می‌کنیم مشکل به وجود می آید، معمولاً توصیه می شود که به جای آن از Rigid Area استفاده شود.




container.add(firstComponent);

container.add(Box.createHorizontalStrut());

یا

container.add(Box.createVerticalStrut ());

container.add(secondComponent);



4- custom : می توان بوسیله ی این شیوه کامپوننتی ایجاد کرد که به اندازه دلخواه ما دارای سایز ماکسیمم ، مینیمم و مرجع باشد. به كد زير دقت كنيد:



container.add(firstComponent);

Dimension minSize = new Dimension(5, 100);

Dimension prefSize = new Dimension(5, 100);

Dimension maxSize = new Dimension(Short.MAX_VALUE, 100);

container.add(new Box.Filler(minSize, prefSize, maxSize));

container.add(secondComponent);


اكنون برنامه BoxLayout2.java را اجرا نماييد. اين برنامه همه تكنيك هاي قبل را بصورت يكجا در خود جمع كرده است. خروجي اين برنامه بصورت زير مي‌باشد.


http://pnu-club.com/../pic/37-14.JPG