آشنایی با کلاس های Swing مرتبط با فریم و پنجره


تا این مرحله از آموزش های مرتبط با طراحی رابط گرافیکی در زبان برنامه نویسی جاوا تا حدودی با ساختار GUI آشنا شدیم. حال در این آموزش قصد داریم تا کمی ریشه ای تر مباحث مربوط به طراحی GUI را دنبال کنیم.

وقتی که ما با طراحی GUI سر و کار داریم، به طور کلی با دو مفهوم Component و Container بایستی آشنا باشیم. واژه Component به معنی "عنصر، قطعه، جزء سازنده چیزی و ..." است. در طراحی GUI این اصطلاح به هر آنچه که روی GUI قرار گیرد گفته می شود مثل دکمه، اسلایدر، منو و ....

واژه Container به معنی "ظرف" است. در جاوا Container به چارچوبی گفته می شود که دیگر Component ها مثل دکمه و ... داخل آن قرار می گیرند که این ظرف معمولا یک فریم یا پنجره است. بنابراین می توان این نتیجه را گرفت که برای ساخت یک GUI ابتدا می بایست یک فریم ایجاد کرد تا بتوان دیگر Component ها را داخل آن قرار داد.

در این مرحله می بایست با تفاوت مابین Window و Frame آشنا شویم. به طور کلی Window یا "پنجره" به چارچوبی گفته می شود بسیار ساده بوده که نه Title یا "عنوان" دارد و نه دیگر دکمه هایی که در بالای یک پنجره به طور معمول قرار دارند مثل دکمه بستن پنجره و ... اما این در حالی است که یک Frame تا حدودی پیشرفته تر از Window است که حاوی عنوان و دکمه هایی برای بستن، بزرگ و کوچک کردن پنجره و ... است.

در Swing برای استفاده از پنجره و فریم می بایست از کلاس های JFrame و JWindow استفاده کرد (پیش از این با کلاس JFrame آشنا شده ایم. برای کسب اطلاعات بیشتر در این زمینه به آموزش 69 مراجعه نمایید).

در آموزش قبل دیدیم که به چه شکل می توان از کلاس JFrame برای ساخت GUI استفاده کرد (باز هم یاد آور می شویم که GUI مخفف واژگان Graphical User Interface به معنی "رابط گرافیکی کاربر" است). در این آموزش قصد داریم تا با استفاده از وارثت از این کلاس استفاده کنیم.

برای آنکه از کلاس JFrame استفاده کنیم ابتدا می بایست تا این کلاس را به برنامه خود اصطلاحاً import کنیم. برای این منظور ابتدا روی دسکتاپ فولدری تحت عنوان 70th Session ایجاد کرده و داخل آن فایلی با نامی دلخواه اما حتما با پسوند .java ایجاد می کنیم (در این مثال نام myClass برای این فایل در نظر گرفته شده است). حال کد زیر را در اولین خط از فایل جاوای خود می نویسیم:

Import javax.swing.*;

با این کار، کلیه کلاس های swing را به برنامه خود فرا خواهیم خواند.

حال قصد داریم تا کلاس اصلی برنامه ما خصوصیات خود را از کلاس JFrame جاوا به ارث ببرد. برای این منظور فایل خود را به صورت زیر تکمیل می کنیم:

import javax.swing.*;
public class myClass extends JFrame{

}

همانطور که می بینیم، نام کلاس اصلی برنامه با نام فایل جاوا یکی است که در غیر این صورت برنامه با مشکل مواجه خواهد شد. سپس با استفاده از کلید واژه extends این دستور را به برنامه می دهیم که کلاس ما کلیه خصوصیات خود را از کلاس JFrame به ارث ببرد.

حال نیاز به یک Constructor داریم تا از آن طریق بتوان خصوصیات این کلاس را تعریف کرد (برای آشنایی با مبحث Constructor ها به آموزش 41 مراجعه نمایید). برای این منظور کد فوق را به صورت زیر تکمیل می کنیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
    }
}

همانطور که پیش از این توضیح داده ایم، نام یک Constructor می بایست دقیقاً با نام کلاس اصلی برنامه یکی باشد. حال برای آنکه برنامه ما تکمیل شود می بایست کارهای زیر انجام شوند:

Constructor مرتبط با کلاس JFrame به برنامه فرا خوانده شود.

عنوانی برای این فریم یا پنجره در نظر گرفته شود.

اندازه ای برای این پنجره در نظر گرفته شود.

ظاهر پنجره تعریف شود.

دستور دهیم که وقتی پنجره بسته می شود چه اتقافی رخ دهد.

و همچنین کاری کنیم که این پنجره Visible یا "قابل رویت" شود.

حال ممکن است این سوال پیش بیاید که ما در این مثال از JFrame استفاده کرده ایم پس چرا در موارد فوق از معادل "پنجره" استفاده کرده ایم. در پاسخ به این سوال بایستی گفت با توجه به اینکه عبارت "پنجره" در میان کاربران جا افتاده است، ما هم به جای "فریم" از اصطلاح "پنجره" استفاده می کنیم. به عبارت دیگر چه از JWindow و چه از JFrame استفاده کنیم معادل آن ها را "پنجره" قلمداد خواهیم کرد.

حال قصد داریم برای این پنجره ای که قرار است ایجاد کنیم یک Title یا "عنوان" در نظر بگیریم. برای این منظور کد فوق را به صورت زیر تکمیل می کنیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
    }
}

همانطور که می بینیم از متدی تحت عنوان setTitle(); برای این کار استفاده کرده ایم. از آنجا که قصد داریم متنی را داخل پرانتزهای این متد وارد نماییم، از اینرو از علامت های " " استفاده خواهیم کرد. داخل دو علامت " " عبارت This is my first window به معنی "این اولین پنجره من است" را وارد کرده ایم. در واقع این عبارت در گوشه بالا سمت چپ پنجره ما همواره به نمایش در خواهد آمد.

در ادامه می خواهیم از متد دیگری استفاده کنیم که این وظیفه را دارا است تا ابعداد پنجره ما را مشخص سازد. متد setSize(); که این کار را برای ما انجام می دهد دو پارامتر می تواند داشته باشد که با یک کاما از یکدیگر جدا می شوند:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        setSize(300, 120);
    }
}

پارامتر اول که در این مثال معادل با عدد 300 است این وظیفه را دارا است تا width یا "عرض" پنجره را تعیین کند و پارمتر دوم که اصطلاحاً height گفته می شود مسئول تعیین اندازه "ارتفاع" پنجره می باشد (توجه داشته باشیم که عبارت height به صورت "هایت" تلفظ می شود).

هر پنجره ای در سیستم عامل ویندوز حاوی یک علامت ضربدر کوچک در بالا است که کاربران از آن طریق می توانند پنجره را ببندند. برای افزودن چنین امکانی به پنجره خود می بایست از متدی تحت عنوان setDefaultCloseOperation(); استفاده نمود. این متد می تواند چهار پارامتر مختلف داشته باشد که در آموزش های قبل با یکی از آن ها آشنا شدیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        setSize(300, 120);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}


پارامتر JFrame.EXIT_ON_CLOSE این دستور را به سیستم می دهد که به محض کلیک شدن دکمه ضربدر که مسئول بستن پنجره است، از برنامه هم خارج شویم. حال ممکن است این سوال پیش آید که خب به محض بستن پنجره از برنامه خارج خواهیم شد اما این دیدگاه درست نیست. چرا که ما می توانیم پنجره را بسته اما همواره داخل برنامه باشیم و برنامه ما به اتمام نرسیده باشد.

پارامتر JFrame.DISPOSE_ON_CLOSE این امکان را برای ما فراهم می سازد که بر خلاف متدی که در کد فوق از آن استفاده کرده ایم، از پنجره خارج شده و بخشی از حافظه که به آن اختصاص داده شده بود آزاد می شود اما برنامه ما می تواند کماکان در حال اجرا باشد.

پارامتر JFrame.DO_NOTHING_ON_CLOSE هیچ کار خاصی انجام نخواهد داد، پنجره باز می ماند و برنامه در حال اجرا باقی می ماند.

پارامتر JFrame.HIDE_ON_CLOSE باعث می گردد که پنجره از دید پنهان شود اما این در حالی است که پنجره به طور کامل بسته نشده و اگر بخواهیم می توانیم باز هم آن را نمایش دهیم.

در ادامه برای آنکه بتوانیم پنجره خود را نمایان سازیم می بایست از متدی تحت عنوان setVisible(); استفاده کرده و پارامتر را true را برای آن در نظر بگیریم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        setSize(300, 120);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}

حال اگر بخواهیم که این پنجره نمایان نشود، به سادگی می توان پارامتر false را برای این متد در نظر گرفت.

در این مرحله کدهای برنامه ما تقریباً تکمیل شده اند اما همان طور که پیش از این توضیح داده ایم، هر برنامه ای که با زبان برنامه نویسی جاوا نوشته شود نیاز به یک متد از جنس main دارد که به منزله نقطه شروع برنامه خواهد بود. بنابراین این برنامه هم از این قاعده مستثنی نبوده و نیاز به یک متد main دارد:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        setSize(300, 120);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] arguments) {
        myClass test = new myClass();
    }
}

همانطور که در کد فوق می بینیم، متد main را خارج از Block مربوط به Constructor تعریف کرده ایم (منظور از Block هر آنچه که داخل دو علامت { } قرار گیرد می باشد). سپس از روی کلاس اصلی برنامه شیئی ساخته ایم تحت عنوان test که پیش از این به طور کامل پیرامون نحوه ایجاد شیئ ها در زبان برنامه نویسی جاوا صحبت کرده ایم.

حال می توان پس از Compile کردن برنامه خود آن را اجرا کنیم:

می بینیم که پنجره ما در گوشه بالا سمت چپ نمایان می شود و علت این مسئله آن است که از متد setBounds(); که علاوه بر اندازه، جایگاه پنجره را هم مشخص می سازد استفاده نکرده ایم. برای استفاده از آن، می توان متد setSize(); را کامنت کرده و در عوض به همان صورت که در کد زیر مشاهده می شود از متد setBounds(); استفاده نماییم.

حال ممکن است این سوال پیش بیاد که چه نیازی به کامنت کردن متد setSize(); داریم. در پاسخ به این سوال می بایست گفت که با توجه به اینکه متد setBounds(); می تواند چهار پارامتر داشته باشد که دو تای آن ها مربوط به اندازه هستند، پس به راحتی می توان با یک تیر دو نشان را زد:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        setSize(300, 120);
        //setBounds(600, 200, 300, 120);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] arguments) {
        myClass test = new myClass();
    }
}

حال مجدد می توان برنامه خود را Compile و اجرا کرد (برای توضیحات بیشتر پیرامون متد setBounds(); به آموزش 69 مراجعه نمایید):


می بینیم که این بار پنجره تقریباً در وسط مانیتور قرار گرفته است.

پیش از اتمام آموزش قصد داریم پارامترهای مختلف متد setDefaultCloseOperation(); را مورد بررسی قرار دهیم. در کد فوق که پارامتر JFrame.DISPOSE_ON_CLOSE در نظر گرفته شده است. یک بار دیگر به صورت زیر برنامه را اجرا می کنیم:

می بینیم بعد از آن که دستور java myClass را در محیط cmd اجرا کردیم، هیچ دستور دیگری اجرا نشده است. حال همانطور که در کد فوق با یک فلش قرمز رنگ مشخص شده، به محض کلیک کردن روی دکمه ضربدر پنجره برنامه خود با حالت زیر مواجه خواهیم شد:

می بینیم که با موفقیت از برنامه خارج می شویم و در صورت تمایل می توانیم دستورات جدیدی را وارد پنجره cmd کنیم. حال کد فوق را به صورت زیر ویرایش می کنیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        //setSize(300, 120);
        setBounds(600, 200, 300, 120);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] arguments) {
        myClass test = new myClass();
    }
}

همانطور که در کد فوق می بینیم، از پارامتر JFrame.DISPOSE_ON_CLOSE استفاده کرده ایم. در این صورت اگر دکمه ضربدر پنجره را کلیک کنیم، پنجره بسته خواهد شد. این پارامتر عملکردی همچون EXIT_ON_CLOSE خواهد داشت.

حال کد فوق را به صورت زیر بازنویسی می کنیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        //setSize(300, 120);
        setBounds(600, 200, 300, 120);
        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] arguments) {
        myClass test = new myClass();
    }
}

مجدد برنامه خود را پس از Compile کردن اجرا می کنیم:


در تصویر فوق علامت ضربدر با یک فلش قرمز رنگ مشخص شده است اما با توجه به نوع پارامتری که برای برنامه خود در نظر گرفته ایم، هر چه قدر هم که روی دکمه ضربدر کلیک کنیم برنامه بسته نخواهد شد و حتی اگر روی آیکان مرتبط با برنامه که در Taskbar قرار می گیرد هم کلیک راست کرده و Close Window را بزنیم باز هم برنامه بسته نخواهد شد:

در واقع تنها راه بستن این برنامه، کلیک کردن روی دکمه ضربدر برنامه cmd می باشد.

حال کدهای فوق را به صورت زیر بازنویسی می کنیم:

import javax.swing.*;
public class myClass extends JFrame{
    public myClass() {
        setTitle("This is my first window");
        //setSize(300, 120);
        setBounds(600, 200, 300, 120);
        setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
        setVisible(true);
    }
    public static void main(String[] arguments) {
        myClass test = new myClass();
    }
}

مجدد برنامه را اجرا می کنیم:

حال روی دکمه ضربدر برنامه کلیک می کنیم:

می بینیم که پس از بستن پنجره از برنامه خارج نشده ایم چرا که پارامتر در نظر گرفته شده صرفاً پنجره را پنهان می سازد. به عبارت دیگر داخل پنجره cmd هیچ دستوری نمی توان وارد ساخت چرا که هنوز داخل برنامه خود می باشیم.



بهزاد مرادی

لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
کاربر میهمان
محمدمن یک کاربر مهمان هستم
۱۳۹۵/۰۸/۲۵
سلام
ممنون از آموزش های عالی و بسیار خوبتون