5. رابطهای کاربری گرافیکی
در اینجا هدف ما نشان دادن نحوه ساخت رابطهای کاربری گرافیکی با JAVA است. ابتدا، به کلاسهای پایهای که امکان ساخت یک رابط کاربری گرافیکی را برای ما فراهم میکنند، نگاهی خواهیم انداخت. در ابتدا، از هیچ ابزار تولید خودکار استفاده نخواهیم کرد. سپس از JBuilder، یک ابزار توسعه از Borland/Inprise که توسعه برنامههای جاوا و به ویژه ساخت رابطهای کاربری گرافیکی را تسهیل میکند، استفاده خواهیم کرد.
5.1. مبانی رابطهای کاربری گرافیکی
5.1.1. یک پنجره ساده
کد زیر را در نظر بگیرید:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
//کلاس فرم
public class form1 extends JFrame {
// سازنده
public form1() {
// عنوان پنجره
this.setTitle("Mon premier formulaire");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
}//سازنده
// تابع آزمایشی
public static void main(String[] args) {
// فرم نمایش داده میشود
new form1().setVisible(true);
}
}//کلاس
اجرای کد بالا پنجره زیر را نمایش میدهد:

یک رابط کاربری گرافیکی معمولاً از کلاس پایه JFrame مشتق میشود:
public class form1 extends JFrame {
کلاس پایه JFrame یک پنجرهٔ پایه را با دکمههای بستن و حداکثر/حداقل کردن، اندازهٔ قابل تنظیم و غیره تعریف میکند و رویدادهای این اشیاء گرافیکی را مدیریت میکند. در اینجا با تنظیم عنوان، عرض (۳۰۰ پیکسل) و ارتفاع (۱۰۰ پیکسل) آن، کلاس پایه را تخصصی میکنیم. این کار در سازندهٔ آن انجام میشود:
// سازنده
public form1() {
// عنوان پنجره
this.setTitle("Mon premier formulaire");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
}//سازنده
عنوان پنجره توسط متد setTitle و ابعاد آن توسط متد setSize تعیین میشود. این متد یک شیء Dimension(largeur,hauteur) را بهعنوان پارامتر میپذیرد، که در آن largeur و hauteur بهترتیب عرض و ارتفاع پنجره را به پیکسل نشان میدهند.
روش main برنامه گرافیکی را به شرح زیر راهاندازی میکند:
new form1().setVisible(true);
سپس یک فرم از نوع form1 ایجاد میشود (new form1()) و نمایش داده میشود (setVisible(true))، و پس از آن، برنامه به رویدادهای رخداده روی فرم (کلیکها، حرکات ماوس، ... و رویدادهایی را که فرم مدیریت میکند، فعال میکند. در این مورد، فرم ما هیچ رویدادی را به جز رویدادهایی که توسط کلاس پایه JFrame مدیریت میشوند (کلیک روی دکمههای بستن و حداکثر/حداقل کردن، تغییر اندازه پنجره، جابجایی پنجره و غیره) مدیریت نمیکند.
هنگام تست این برنامه با اجرای آن از یک پنجره DOS با استفاده از:
هنگام اجرای فایل form1.class، متوجه خواهید شد که وقتی پنجرهای که نمایش داده شده را میبندید، کنترل به پنجره DOS بازنمیگردد، گویی که برنامه به پایان نرسیده است. این در واقع درست است. برنامه به شرح زیر اجرا میشود:
- در ابتدا، یک نخ اجرای اول برای اجرای متد main راهاندازی میشود
- هنگامی که این متد فرم را ایجاد و نمایش میدهد، یک نخ دوم برای رسیدگی به رویدادهای خاص مربوط به فرم ایجاد میشود
- پس از انجام این کار، و در مثال ما، نخ مربوط به متد main متوقف میشود و تنها نخ اجرای رابط کاربری (GUI) باقی میماند.
- وقتی پنجره بسته میشود، ناپدید میشود اما نخ (thread)ی را که در آن اجرا میشد متوقف نمیکند.
- فعلاً، ما مجبوریم این نخ را با فشردن Ctrl-C در پنجره DOS که برنامه از آن اجرا شده است، متوقف کنیم.
بیایید وجود دو نخ (thread) مجزا را بررسی کنیم: یکی نخی که متد main در آن در حال اجراست و دیگری نخی که پنجره گرافیکی در آن در حال اجراست:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
import java.io.*;
// کلاس فرم
public class form1 extends JFrame {
// سازنده
public form1() {
// عنوان پنجره
this.setTitle("Mon premier formulaire");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
}//سازنده
// تابع آزمایشی
public static void main(String[] args) {
// ردیابی
System.out.println("Début du thread main");
// فرم نمایش داده میشود
new form1().setVisible(true);
// ردیابی
System.out.println("Fin du thread main");
}//اصلی
}//کلاس
اجرای کد نتایج زیر را تولید میکند:

مشاهده میشود که تِرد main در حالی که پنجره هنوز نمایش داده میشود، متوقف شده است. بستن پنجره، تِردی را که در آن در حال اجرا بود متوقف نمیکند. برای متوقف کردن این تِرد، دوباره کلیدهای Ctrl-C را در پنجره DOS فشار دهید.
برای پایان این مثال، به پکیجهای واردشده توجه کنید:
- javax.swing برای کلاس JFrame
- java.awt برای کلاس Dimension
5.1.2. پردازش یک رویداد
در مثال قبلی، ما باید خودمان بستهشدن پنجره را مدیریت میکردیم تا وقتی این اتفاق میافتد، برنامه خاتمه یابد – کاری که در حال حاضر انجام نمیشود. برای این کار، باید یک شیء ایجاد کنیم که به رویدادهای رخداده روی پنجره «گوش فرا دهد» و رویداد «بستهشدن پنجره» را تشخیص دهد. این شیء «گوشدهنده» یا پردازشگر رویداد نامیده میشود. انواع مختلفی از پردازشگرها برای رویدادهای گوناگونی که ممکن است در اجزای یک رابط کاربری گرافیکی رخ دهند، وجود دارد. برای مؤلفه JFrame، گوشدهنده WindowListener نامیده میشود و یک رابط است که متدهای زیر را تعریف میکند (به مستندات جاوا مراجعه کنید)
خلاصه متدها | ||
void | windowActivated(WindowEvent e) پنجره فعال میشود | |
خالی | پنجره بسته شد(WindowEvent e) پنجره بسته شد | |
خالی | windowClosing(WindowEvent e) کاربر یا برنامه درخواست بستهشدن پنجره را داد | |
void | پنجره غیرفعال شد(WindowEvent e) پنجره دیگر پنجره فعال نیست | |
void | windowDeiconified(WindowEvent e) پنجره از حالت کوچکشده به حالت عادی بازمیگردد | |
void | windowIconified(WindowEvent e) پنجره از وضعیت عادی به وضعیت کوچکشده تغییر میکند | |
void | windowOpened(WindowEvent e) پنجره برای اولین بار قابل مشاهده میشود | |
بنابراین هفت رویداد وجود دارد که میتوان آنها را مدیریت کرد. همهٔ رویدادپردازها یک شیء از نوع WindowEvent را بهعنوان پارامتر دریافت میکنند که فعلاً آن را نادیده میگیریم. رویداد مورد نظر در اینجا بستهشدن پنجره است که باید توسط متد windowClosing مدیریت شود. برای مدیریت این رویداد، میتوانیم یک شیء Windowlistener را با استفاده از یک کلاس ناشناس به صورت زیر ایجاد کنیم:
//ایجاد یک رویدادپرداز
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//تعریف Win
پردازشگر رویداد ما که رابط WindowListener را پیادهسازی میکند، باید هر هفت متد این رابط را تعریف کند. از آنجا که ما تنها میخواهیم بستهشدن پنجره را مدیریت کنیم، تنها برای متد windowClosing کد تعریف میکنیم. وقتی رویدادهای دیگر رخ دهند، به ما اطلاع داده خواهد شد اما هیچ اقدامی انجام نخواهیم داد. وقتی به ما اطلاع داده شود که پنجره در حال بسته شدن است (windowClosing)، چه خواهیم کرد؟ برنامه را خاتمه خواهیم داد:
public void windowClosing(WindowEvent e){System.exit(0);}
در اینجا یک شیء داریم که قادر به رسیدگی به رویدادهای پنجره به طور کلی است. چگونه آن را با یک پنجرهٔ خاص مرتبط کنیم؟ کلاس JFrame دارای متدی به نام addWindowListener(WindowListener win) است که امکان اختصاص یک شنونده رویداد «پنجره» به یک پنجرهٔ مشخص را فراهم میکند. بنابراین در اینجا، در سازندهٔ پنجره، خواهیم نوشت:
//ایجاد یک رویدادپرداز
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//تعریف ویندوز
// این دستپرداز رویدادها رویدادهای پنجرهٔ جاری را مدیریت خواهد کرد
this.addWindowListener(win);
برنامه کامل به شرح زیر است:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
// کلاس فرم
public class form2 extends JFrame {
// سازنده
public form2() {
// عنوان پنجره
this.setTitle("Mon premier formulaire");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
// ایجاد یک رویدادپرداز
WindowListener win=new WindowListener(){
public void windowActivated(WindowEvent e){}
public void windowClosed(WindowEvent e){}
public void windowClosing(WindowEvent e){System.exit(0);}
public void windowDeactivated(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowIconified(WindowEvent e){}
public void windowOpened(WindowEvent e){}
};//تعریف وین
// این دستپرداز رویداد، رویدادها را برای پنجرهٔ جاری مدیریت خواهد کرد
this.addWindowListener(win);
}//سازنده
// تابع آزمایشی
public static void main(String[] args) {
// فرم نمایش داده میشود
new form2().setVisible(true);
}//اصلی
}//کلاس
پکیج java.awt.event شامل رابط WindowListener است. هنگامی که این برنامه اجرا میشود و پنجرهای که ظاهر شده بسته میشود، پنجره فرمان که برنامه از آن اجرا شده است، پیامی را نمایش میدهد که نشان میدهد برنامه به پایان رسیده است، که این امر قبلاً رخ نمیداد.
در برنامه ما، ایجاد ابجکتی که مسئول رسیدگی به رویدادهای پنجره است، تا حدی دستوپاگیر است، زیرا مجبوریم متدهایی را حتی برای رویدادهایی که نمیخواهیم رسیدگی کنیم، تعریف کنیم. در این مورد، به جای استفاده از رابط WindowListener، میتوانیم از کلاس WindowAdapter استفاده کنیم. این کلاس رابط WindowListener را با هفت متد خالی پیادهسازی میکند. با ارثبری از کلاس WindowAdapter و بازتعریف تنها متدهایی که به آنها علاقهمند هستیم، به همان نتیجهٔ رابط WindowListener میرسیم، اما بدون نیاز به تعریف متدهایی که به آنها علاقهای نداریم. توالی
- تعریف رویدادپرداز
- وابستهسازی هندلر به پنجره
میتواند در مثال ما به شرح زیر انجام شود:
//ایجاد یک رویدادپرداز
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//تعریف Win
// این دستپرداز رویدادها رویدادهای پنجرهٔ جاری را مدیریت خواهد کرد
this.addWindowListener(win);
در اینجا ما از یک کلاس ناشناس استفاده میکنیم که از کلاس WindowAdapter ارث میبرد و متد windowClosing آن را مجدداً تعریف میکند. برنامه سپس به این صورت درمیآید:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
//کلاس فرم
public class form2 extends JFrame {
// سازنده
public form2() {
// عنوان پنجره
this.setTitle("Mon premier formulaire");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
// ایجاد یک رویدادپرداز
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//تعریف Win
// این دستپرداز رویدادها رویدادهای پنجرهٔ جاری را مدیریت خواهد کرد
this.addWindowListener(win); }//سازنده
// تابع آزمایشی
public static void main(String[] args) {
// فرم نمایش داده میشود
new form2().setVisible(true);
}//اصلی
}//کلاس
این برنامه همان نتایج برنامه قبلی را تولید میکند اما نوشتن آن سادهتر است.
5.1.3. یک فرم با یک دکمه
حال بیایید یک دکمه به پنجره خود اضافه کنیم:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
//کلاس فرم
public class form3 extends JFrame {
// یک دکمه
JButton btnTest=null;
Container conteneur=null;
// سازنده
public form3() {
// عنوان پنجره
this.setTitle("Formulaire avec bouton");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
// ایجاد یک رویدادگیر
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//تعریف Win
// این دستپرداز رویداد برای پنجرهٔ جاری رویدادها را مدیریت خواهد کرد
this.addWindowListener(win);
// بازیابی کانتینر پنجره
conteneur=this.getContentPane();
// ما یک مدیر چیدمان مؤلفه را برای این کانتینر انتخاب میکنیم
conteneur.setLayout(new FlowLayout());
// ما یک دکمه ایجاد میکنیم
btnTest=new JButton();
// برچسب آن را تنظیم کنید
btnTest.setText("Test");
// افزودن دکمه به کانتینر
conteneur.add(btnTest);
}//سازنده
// توابع آزمایشی
public static void main(String[] args) {
// نمایش فرم
new form3().setVisible(true);
}//اصلی
}//کلاس
یک پنجره JFrame دارای یک کانتینر است که میتوان اجزای گرافیکی (دکمهها، چکباکسها، لیستهای کشویی و غیره) را در آن قرار داد. این کانتینر از طریق متد getContentPane کلاس JFrame قابل دسترسی است:
Container conteneur=null;
..........
// بازیابی کانتینر پنجره
conteneur=this.getContentPane();
هر مؤلفه با استفاده از متد add از کلاس Container در کانتینر قرار میگیرد. بنابراین، برای قرار دادن مؤلفه C در شیء قبلی conteneur، خواهیم نوشت:
این کامپوننت در کجای کانتینر قرار میگیرد؟ مدیرهای چیدمان کامپوننت مختلفی با نام XXXLayout وجود دارند، که برای مثال XXX معادل Border، Flow، ... هر مدیر چیدمان ویژگیهای خاص خود را دارد. برای مثال، مدیر چیدمان FlowLayout اجزا را در ردیفهایی از بالای فرم مرتب میکند. پس از پر شدن یک ردیف، اجزا در ردیف بعدی قرار میگیرند. برای مرتبط کردن یک مدیر چیدمان با یک پنجره JFrame، از متد setLayout از کلاس JFrame به شکل زیر استفاده کنید:
بنابراین، در مثال ما، برای مرتبط کردن یک دستگیره از نوع FlowLayout با پنجره، نوشتیم:
// یک مدیر چیدمان مؤلفه برای این کانتینر انتخاب کنید
conteneur.setLayout(new FlowLayout());
امکان حذف هندلر چیدمان و نوشتن به شکل زیر وجود دارد:
در این حالت، شما باید مختصات دقیق کامپوننت را در داخل کانتینر به صورت (x, y, width, height) مشخص کنید، که در آن (x, y) مختصات گوشه بالا سمت چپ کامپوننت در داخل کانتینر هستند. این روشی است که از این پس بیشترین استفاده را از آن خواهیم کرد.
اکنون میدانیم که اجزا چگونه در داخل کانتینر (add) و در کجا (setLayout) قرار میگیرند. تنها کاری که باقی مانده، شناسایی ... است.
کامپوننتهایی که میتوان آنها را در یک کانتینر قرار داد. در اینجا، ما یک دکمه را که توسط کلاس javax.swing.JButton مدلسازی شده است، قرار میدهیم:
JButton btnTest=null;
..........
// ایجاد یک دکمه
btnTest=new JButton();
// برچسب آن را تنظیم کنید
btnTest.setText("Test");
// افزودن دکمه به کانتینر
conteneur.add(btnTest);
هنگامی که این برنامه را اجرا میکنید، پنجره زیر ظاهر میشود:

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

این اصلیترین مزیت مدیران چیدمان است: آنها چیدمان یکنواخت اجزا را هنگام تغییر اندازهٔ کانتینر حفظ میکنند. بیایید از مدیر چیدمان null استفاده کنیم تا تفاوت را ببینیم. دکمه اکنون با دستورالعملهای زیر درون کانتینر قرار میگیرد:
// یک مدیر چیدمان کامپوننت برای این کانتینر انتخاب کنید
conteneur.setLayout(null);
// ایجاد یک دکمه
btnTest=new JButton();
// برچسب آن را تنظیم کنید
btnTest.setText("Test");
// موقعیت و ابعاد آن را تنظیم کنید
btnTest.setBounds(10,20,100,20);
// افزودن دکمه به کانتینر
conteneur.add(btnTest);
در اینجا، ما صراحتاً دکمه را در نقطه (10,20) روی فرم قرار میدهیم و ابعاد آن را به عرض 100 پیکسل و ارتفاع 20 پیکسل تنظیم میکنیم. پنجره جدید به شکل زیر است:

اگر پنجره تغییر اندازه دهد، دکمه در همان موقعیت باقی میماند.

اگر روی دکمه Test کلیک کنید، هیچ اتفاقی نمیافتد. این به این دلیل است که ما هنوز یک رویدادپرداز به دکمه اختصاص ندادهایم. برای پی بردن به اینکه چه نوع رویدادپردازهایی برای یک کامپوننت مشخص در دسترس هستند، میتوانید در تعریف کلاس به دنبال متدهایی مانند addXXXListener بگردید که به شما امکان میدهند یک رویدادپرداز را با آن کامپوننت مرتبط کنید. کلاس javax.swing.JButton از کلاس javax.swing.AbstractButton ارث میبرد که شامل متدهای زیر است:
خلاصه متدها | ||
void | addActionListener(ActionListener l) | |
void | addChangeListener(ChangeListener l) | |
void | addItemListener(ItemListener l) | |
در اینجا باید به مستندات مراجعه کنید تا بفهمید کدام رویدادپرداز، کلیک دکمه را مدیریت میکند. این رابط ActionListener است. این رابط تنها یک متد را تعریف میکند:
خلاصه متدها | ||
void | actionPerformed(ActionEvent e) | |
این متد یک پارامتر به نام ActionEvent میگیرد که فعلاً آن را نادیده میگیریم. برای رسیدگی به کلیکهای دکمه btntest در برنامه خود، ابتدا یک رویدادپرداز به آن اختصاص میدهیم:
btnTest.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt){
btnTest_clic(evt);
}
}//کلاس ناشناس
);//دستپرداز رویداد
در اینجا، متد actionPerformed به متد btnTest_clic اشاره دارد که به شرح زیر تعریف میکنیم:
public void btnTest_clic(ActionEvent evt){
// لاگگیری کنسول
System.out.println("clic sur bouton");
}//btnTest_click
هر بار که کاربر دکمه Test را کلیک میکند، پیامی به کنسول نوشته میشود. این موضوع در اجرای زیر نشان داده شده است:

برنامه کامل به شرح زیر است:
//کلاسهای واردشده
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
//کلاس فرم
public class form4 extends JFrame {
//یک دکمه
JButton btnTest=null;
Container conteneur=null;
// سازنده
public form4() {
// عنوان پنجره
this.setTitle("Formulaire avec bouton");
//ابعاد پنجره
this.setSize(new Dimension(300,100));
// ایجاد یک رویدادپرداز
WindowAdapter win=new WindowAdapter(){
public void windowClosing(WindowEvent e){System.exit(0);}
};//تعریف ویندوز
// این دستپرداز رویداد برای پنجرهٔ جاری رویدادها را مدیریت خواهد کرد
this.addWindowListener(win);
// ما کانتینر پنجره را بازیابی میکنیم
conteneur=this.getContentPane();
// ما یک مدیر چیدمان برای اجزا در این کانتینر انتخاب میکنیم
conteneur.setLayout(null);
// ما یک دکمه ایجاد میکنیم
btnTest=new JButton();
// برچسب آن را تنظیم کنید
btnTest.setText("Test");
//موقعیت و ابعاد آن را تنظیم کنید
btnTest.setBounds(10,20,100,20);
// یک رویدادپرداز به آن اختصاص دهید
btnTest.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt){
btnTest_clic(evt);
}
}//کلاس ناشناس
);//دستپرداز رویداد
// افزودن دکمه به کانتینر
conteneur.add(btnTest);
}//سازنده
public void btnTest_clic(ActionEvent evt){
//ردیابی کنسول
System.out.println("clic sur bouton");
}//btnTest_click
// تابع آزمایشی
public static void main(String[] args) {
// فرم نمایش داده میشود
new form4().setVisible(true);
}//اصلی
}//کلاس
5.1.4. پردازشگرهای رویداد
کامپوننتهای اصلی Swing که بررسی خواهیم کرد عبارتند از پنجرهها (JFrame)، دکمهها (JButton)، چکباکسها (JCheckBox)، دکمههای رادیویی (JButtonRadio)، لیستهای کشویی (JComboBox)، لیستها (JList)، اسلایدرها (JScrollBar)، برچسبها (JLabel)، کادرهای متنی تکخطی (JTextField) یا کادرهای متنی چندخطی (JTextArea)، منوها (JMenuBar)، موارد منو (JMenuItem).
جدولهای زیر برخی از دستگیرکنندههای رویداد و رویدادهایی را که به آنها مرتبط هستند، فهرست میکنند.
پردازشگر | کامپوننت(ها) | روش ثبتنام | رویداد |
ActionListener | JButton, JCheckbox, JButtonRadio, JMenuItem | public void addActionListener(ActionListener) | روی دکمه، چکباکس، دکمهٔ رادیویی یا آیتم منو کلیک کنید |
JTextField | |||
ItemListener | JComboBox, JList | public void addItemListener(ItemListener) | مورد انتخابی تغییر کرده است |
InputMethodListener | JTextField, JTextArea | public void addMethodInputListener(InputMethodListener) | متن در فیلد ورودی تغییر کرده است یا مکاننما جابجا شده است |
CaretListener | JTextField, JTextArea | public void addcaretListener(CaretListener) | موقعیت نشانگر ورودی تغییر کرده است |
AdjustmentListener | JScrollBar | public void addAdjustmentListener(AdjustmentListener) | مقدار درایو تغییر کرده است |
MouseMotionListener | public void addMouseMotionListener(MouseMotionListener) | موشواره جابجا شده است | |
WindowListener | JFrame | public void addWindowlistener(WindowListener) | رویداد پنجره |
MouseListener | public void addMouselistener(MouseListener) | رویدادهای ماوس (کلیک، ورود/خروج از ناحیهٔ یک مؤلفه، فشرده شدن دکمه، رها کردن) | |
FocusListener | public void addFocuslistener(FocusListener) | رویداد فوکوس (به دست آمدن، از دست رفتن) | |
KeyListener | public void addKeylistener(KeyListener) | رویداد صفحهکلید (کلید تایپشده، فشرده، رهاشده) |
کامپوننت | روش ثبت رسیدگیکنندههای رویداد |
JButton | public void addActionListener(ActionListener) |
JCheckbox | public void addItemListener(ItemListener) |
JCheckboxMenuItem | public void addItemListener(ItemListener) |
JComboBox | public void addItemListener(ItemListener) public void addActionListener(ActionListener) |
Container | public void addContainerListener(ContainerListener) |
JComponent | public void addComponentListener(ComponentListener) public void addFocusListener(FocusListener) public void addKeyListener(KeyListener) public void addMouseListener(MouseListener) public void addMouseMotionListener(MouseMotionListener) |
JFrame | public void addWindowlistener(WindowListener) |
JList | public void addItemListener(ItemListener) |
JMenuItem | public void addActionListener(ActionListener) |
JPanel | به عنوان کانتینر |
JScrollPane | بهعنوان کانتینر |
JScrollBar | public void addAdjustmentListener(AdjustmentListener) |
JTextComponent | public void addInputMethodListener(InputMethodListener) public void addCaretListener(CaretListener) |
JTextArea | comme JTextComponent |
JTextField | مانند JTextComponent public void addActionListener(ActionListener) |
تمام کامپوننتها، به جز آنهایی که از نوع TextXXX هستند، از کلاس JComponent مشتق شدهاند و بنابراین متدهای مرتبط با آن کلاس را نیز در اختیار دارند.
5.1.5. متدهای دستپرداز رویداد
جدول زیر متدهایی را که پردازشگرهای رویداد مختلف باید پیادهسازی کنند، فهرست میکند.
رابط | متدها |
ActionListener | public void actionPerformed(ActionEvent) |
AdjustmentListener | public void adjustmentValueChanged(AdjustmentEvent) |
ComponentListener | public void componentHidden(ComponentEvent) public void componentMoved(ComponentEvent) public void componentResized(ComponentEvent) public void componentShown(ComponentEvent) |
ContainerListener | public void componentAdded(ContainerEvent) public void componentRemoved(ContainerEvent) |
FocusListener | public void focusGained(FocusEvent) public void focusLost(FocusEvent) |
ItemListener | public void itemStateChanged(ItemEvent) |
KeyListener | public void keyPressed(KeyEvent) public void keyReleased(KeyEvent) public void keyTyped(KeyEvent) |
MouseListener | public void mouseClicked(MouseEvent) public void mouseEntered(MouseEvent) public void mouseExited(MouseEvent) public void mousePressed(MouseEvent) public void mouseReleased(MouseEvent) |
MouseMotionListener | public void mouseDragged(MouseEvent) public void mouseMoved(MouseEvent) |
TextListener | public void textValueChanged(TextEvent) |
InputmethodListener | public void InputMethodTextChanged(InputMethodEvent) public void caretPositionChanged(InputMethodEvent) |
CaretLisetner | public void caretUpdate(CaretEvent) |
WindowListener | public void windowActivated(WindowEvent) public void windowClosed(WindowEvent) public void windowClosing(WindowEvent) public void windowDeactivated(WindowEvent) public void windowDeiconified(WindowEvent) public void windowIconified(WindowEvent) public void windowOpened(WindowEvent) |
5.1.6. کلاسهای آداپتور
همانطور که در رابط WindowListener دیدیم، کلاسهایی با نام XXXAdapter وجود دارند که رابطهای XXXListener را با متدهای خالی پیادهسازی میکنند. بنابراین یک رویدادپرداز مشتقشده از کلاس XXXAdapter میتواند تنها برخی از متدهای رابط XXXListener را پیادهسازی کند – بهطور مشخص، آنهایی که توسط برنامه کاربردی مورد نیاز هستند.
فرض کنید میخواهیم کلیکهای ماوس روی یک کامپوننت Frame به نام f1 را مدیریت کنیم. میتوانیم یک رویدادپرداز را به صورت زیر به آن مرتبط کنیم:
و بنویسیم:
public class gestionnaireSouris implements MouseListener{
// نوشتن ۵ متد رابط MouseListener
//mouseClicked, ..., mouseReleased)
}//پایان کلاس
با این حال، از آنجایی که ما فقط میخواهیم کلیکهای ماوس را مدیریت کنیم، بهتر است بنویسیم:
public class gestionnaireSouris extends MouseAdapter{
// ما فقط یک متد مینویسیم، متدی که کلیکهای ماوس را مدیریت میکند
public void mouseClicked(MouseEvent evt){
…
}
}//پایان کلاس
جدول زیر کلاسهای آداپتور برای دستگیرکنندههای رویداد مختلف را فهرست میکند:
پردازشگر رویداد | آداپتور |
ComponentListener | ComponentAdapter |
ContainerListener | ContainerAdapter |
FocusListener | FocusAdapter |
KeyListener | KeyAdapter |
MouseListener | MouseAdapter |
MouseMotionListener | MouseMotionAdapter |
WindowListener | WindowAdapter |
5.1.7. نتیجهگیری
ما به تازگی مفاهیم پایهای ایجاد رابطهای کاربری گرافیکی در جاوا را تشریح کردیم:
- ایجاد یک پنجره
- ایجاد کامپوننتها
- ارتباط دادن کامپوننتها با پنجره با استفاده از یک مدیر چیدمان
- ارتباطدادن رسیدگیکنندههای رویداد با کامپوننتها
اکنون، به جای ساخت دستی رابطهای کاربری گرافیکی همانطور که به تازگی انجام دادیم، از JBuilder، یک ابزار توسعه جاوا از Borland/Inprise (نسخه 4)، و supérieure.Nous استفاده خواهیم کرد؛ ما از کامپوننتهای کتابخانه java.swing که در حال حاضر توسط Sun، خالق جاوا، توصیه میشود، استفاده خواهیم کرد.
5.2. ساخت یک رابط کاربری گرافیکی با JBuilder
5.2.1. اولین پروژه JBuilder ما
برای آشنایی با JBuilder، بیایید یک برنامه بسیار ساده بسازیم: یک پنجره خالی.
- JBuilder را راهاندازی کنید و File/New Project را انتخاب کنید. سپس صفحهٔ اول جادوگر ظاهر میشود:

- میدانهای زیر را پر کنید:
نام پروژه | شروع این کار یک فایل پروژه به نام début.jpr در پوشهای که در فیلد «نام دایرکتوری پروژه» مشخص شده است، ایجاد میکند. |
مسیر ریشه | پوشهای را که پوشه پروژه شما قرار است در زیر آن ایجاد شود، مشخص کنید. |
نام پوشه پروژه | نام پوشهای را که تمام فایلهای پروژه در آن قرار خواهند گرفت، مشخص کنید. این پوشه در داخل دایرکتوری مشخصشده در فیلد «مسیر ریشه» ایجاد خواهد شد. |
فایلهای منبع (.java، .html و غیره)، فایلهای مقصد (.class و غیره) و فایلهای پشتیبان میتوانند در دایرکتوریهای مجزا قرار گیرند. اگر این فیلدها را خالی بگذارید، در همان دایرکتوری پروژه قرار خواهند گرفت.
[suivant] را وارد کنید
- یک صفحه تأیید، انتخابهای انجامشده در مرحله قبلی را تأیید میکند

[suivant] را وارد کنید
- یک صفحه جدید از شما میخواهد جزئیات پروژه خود را مشخص کنید:

[terminer] را انتخاب کنید
- مطمئن شوید که گزینه Voir/projet تیک خورده است. باید ساختار پروژه خود را در پنجره سمت چپ مشاهده کنید.

- حالا بیایید یک رابط کاربری گرافیکی برای این پروژه بسازیم. گزینه Fichier/Nouveau/Application را انتخاب کنید:

در فیلد classe، نام کلاسی را که باید ایجاد شود وارد کنید. در اینجا، ما از همان نام پروژه استفاده کردهایم.
[suivant] را انتخاب کنید
- صفحه زیرین ظاهر میشود:

کلاس | interfaceDébut این نام کلاس مربوط به پنجرهای است که باید ایجاد شود |
عنوان | این متنی است که در نوار عنوان پنجره نمایش داده خواهد شد |
توجه داشته باشید که در بالا مشخص کردهایم که پنجره باید هنگام راهاندازی برنامه در مرکز صفحه نمایش قرار گیرد.
[Terminer] را وارد کنید
- اینجاست که JBuilder به کار میآید.
- این فایلهای منبع .java را برای دو کلاسی که نامگذاری کردهایم تولید میکند: کلاس برنامه و کلاس رابط کاربری گرافیکی. این دو فایل در ساختار پروژه در پنجره سمت چپ ظاهر میشوند.

- برای دسترسی به کد تولید شده برای این دو کلاس، کافی است روی فایل .java مربوطه دوبار کلیک کنید. بعداً به سراغ کد تولید شده باز خواهیم گشت.
- اطمینان حاصل کنید که گزینه Voir/Structure تیک خورده باشد. این به شما امکان میدهد ساختار کلاس انتخابشده فعلی را مشاهده کنید (روی فایل .java دوبار کلیک کنید). در اینجا، بهعنوان مثال، ساختار کلاس début آمده است:

در اینجا میتوانید ببینید:
-
کتابخانههای واردشده (imports)
-
اینکه یک سازنده با نام début() وجود دارد
-
اینکه یک متد استاتیک main() وجود دارد
-
که یک ویژگی به نام packFrame وجود دارد
دسترسی به ساختار یک کلاس چه فایدهای دارد؟
-
این به شما نمایی کلی از کلاس میدهد. این زمانی مفید است که کلاس شما پیچیده باشد.
-
میتوانید با کلیک روی آن در پنجره ساختار کلاس، به کد یک متد دسترسی پیدا کنید. باز هم، این زمانی مفید است که کلاس شما صدها خط کد داشته باشد. لازم نیست برای پیدا کردن کدی که به دنبال آن هستید، همه خطوط را پیمایش کنید.
کدی که توسط JBuilder تولید میشود، از قبل قابل استفاده است. Run/Run Project یا F9 را انتخاب کنید تا پنجرهای را که به دنبال آن هستید ببینید:

علاوه بر این، وقتی روی دکمه بستن پنجره کلیک میکنید، به درستی بسته میشود. ما به تازگی اولین رابط کاربری گرافیکی خود را ساختهایم. میتوانیم پروژه خود را با استفاده از گزینه File/Close Projects ذخیره کنیم:

با فشردن Tous، تمام پروژههای نمایش داده شده در پنجره بالا تیک خورده خواهند شد. OK آنها را میبندد. اگر به اندازه کافی کنجکاو باشیم که با استفاده از ویندوز اکسپلورر به پوشه پروژه خود (همان پوشهای که در ابتدای راهاندازی پروژه به ویزارد مشخص شده است) برویم، فایلهای زیر را در آنجا پیدا خواهیم کرد:

در مثال ما، مشخص کرده بودیم که تمام فایلها (منبع .java، مقصد .class، پشتیبان .jpr~) باید در همان پوشه پروژه .jpr باشند.
5.2.2. فایلهای تولیدشده توسط JBuilder برای یک رابط کاربری گرافیکی
حال بیایید نگاهی به فایلهای منبع .java تولیدشده توسط JBuilder بیندازیم. مهم است که بتوانیم آنچه تولید شده را بخوانیم، زیرا اغلب لازم است به این فایلهای تولیدشده کد اضافه کنیم. بیایید با باز کردن پروژهٔ خود شروع کنیم: File/Open Project و پروژهٔ début.jpr را انتخاب کنید. پروژهای را که قبلاً ساختیم مییابیم.
5.2.2.1. کلاس اصلی
بیایید با دوبار کلیک روی نام کلاس début.java در پنجرهای که فهرست فایلهای پروژه را نمایش میدهد، آن را بررسی کنیم. کد زیر را داریم:
import javax.swing.UIManager;
import java.awt.*;
public class début {
boolean packFrame = false;
/**برنامه را بسازید*/
public début() {
interfaceDébut frame = new interfaceDébut();
//اعتبارسنجی فریمها با اندازههای از پیش تعریفشده
//تغییر اندازه فریمها با اطلاعات اندازه ترجیحی – مثلاً بر اساس چیدمان آنها
if (packFrame) {
frame.pack();
}
else {
frame.validate();
}
//مرکز پنجره
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension frameSize = frame.getSize();
if (frameSize.height > screenSize.height) {
frameSize.height = screenSize.height;
}
if (frameSize.width > screenSize.width) {
frameSize.width = screenSize.width;
}
frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
frame.setVisible(true);
}
/**روش اصلی*/
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e) {
e.printStackTrace();
}
new début();
}
}
بیایید روی کد تولید شده نظر بدهیم:
- تابع main ظاهر پنجره (setLookAndFeel) را تنظیم میکند و یک نمونه از کلاس début ایجاد میکند.
- سازنده début() سپس اجرا میشود. این سازنده یک نمونه frame از کلاس پنجره ایجاد میکند (new interfaceDébut()). این نمونه ساخته میشود اما نمایش داده نمیشود.
- سپس پنجره بر اساس اطلاعات موجود برای هر یک از اجزای آن (frame.validate) تغییر اندازه میدهد. سپس با نمایش داده شدن و پاسخ به ورودی کاربر، وجود مستقل خود را آغاز میکند.
- پنجره در مرکز صفحه نمایش قرار میگیرد زیرا این مورد هنگام پیکربندی پنجره با استفاده از ویزارد مشخص شده است.
بیایید ببینیم اگر کد début.java را به حداقلهای لازم کاهش دهیم، چه اتفاقی میافتد، همانطور که در ابتدای این فصل انجام دادیم. بیایید یک کلاس جدید ایجاد کنیم. File/New Class را انتخاب کنید:

کلاس جدید را début2 نامگذاری کنید و نام [Terminer] را تغییر دهید. یک فایل جدید در پروژه ظاهر میشود:

فایل début2.java به سادهترین شکل خود کاهش یافته است:
بیایید کلاس را به صورت زیر تکمیل کنیم:
public class début2 {
// تابع اصلی
public static void main(String args[]){
//پنجره را ایجاد میکند
new interfaceDébut().show(); // یا interfaceDébut.setVisible(true);
}//main
}//class start2
تابع main یک نمونه از پنجره interfaceDébut ایجاد میکند و آن را نمایش میدهد (show). قبل از اجرای پروژهٔ خود، باید توجه داشته باشیم که کلاسی که شامل تابع main است که باید اجرا شود، اکنون کلاس début2 است. روی پروژه début.jpr کلیک راست کرده و گزینه propriétés را انتخاب کنید، سپس برگه Exécution:
21

در اینجا نشان داده شده است که کلاس اصلی début (1) است. برای انتخاب یک کلاس اصلی متفاوت، دکمه (2) را فشار دهید:

début2 را انتخاب کرده و آن را روی [OK] تنظیم کنید.

برای تأیید این انتخاب، [OK] را وارد کنید، سپس پروژه را از طریق Run/Run Project یا F9 اجرا کنید. شما همان پنجرهای را که با کلاس début مشاهده کردید خواهید دید، با این تفاوت که این پنجره مرکزیت ندارد، زیرا این مورد در اینجا مشخص نشده است. از این پس، دیگر کلاس اصلی تولید شده توسط JBuilder را نمایش نخواهیم داد، زیرا همیشه یک کار انجام میدهد: ایجاد یک پنجره. اکنون بر خود کلاس پنجره تمرکز خواهیم کرد.
5.2.2.2. کلاس پنجره
اکنون بیایید نگاهی به کدی که برای کلاس interfaceDébut تولید شده است، بیندازیم:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceDébut extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
/**ساخت فریم*/
public interfaceDébut() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Ma première interface graphique avec Jbuilder");
}
/**جایگزین شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
}
5.2.2.2.1. کتابخانههای وارداتی
اینها کتابخانههای java.awt، java.awt.event و javax.swing هستند. دو مورد اول تنها کتابخانههای موجود برای ساخت رابطهای کاربری گرافیکی در نسخههای اولیهٔ جاوا بودند. کتابخانهٔ javax.swing جدیدتر است. در اینجا برای نوع پنجرهٔ JFrame که در اینجا استفاده میشود، ضروری است.
5.2.2.2.2. ویژگیها
JPanel یک نوع کانتینر است که میتوان کامپوننتها را در آن قرار داد. BorderLayout یکی از انواع مدیر چیدمان موجود برای قرار دادن کامپوننتها در داخل کانتینر است. در تمام مثالهای ما، از مدیر چیدمان استفاده نخواهیم کرد و اجزا را خودمان در یک مکان مشخص درون کانتینر قرار خواهیم داد. برای این کار، از مدیر چیدمان null استفاده خواهیم کرد.
5.2.2.2.3. سازنده پنجره
/**ایجاد فریم*/
public interfaceDébut() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(borderLayout1);
this.setSize(new Dimension(400, 300));
this.setTitle("Ma première interface graphique avec Jbuilder");
}
- سازنده با بیان اینکه رویدادهای پنجره (enableEvents) را مدیریت خواهد کرد شروع میشود، سپس متد jbInit را فراخوانی میکند.
- کانتینر (JPanel) برای پنجره (JFrame) بازیابی میشود (getContentPane)
- مدیر چیدمان تنظیم میشود (setLayout)
- اندازه پنجره تنظیم شده است (setSize)
- عنوان پنجره تنظیم شده است (setTitle)
5.2.2.2.4. پردازشگر رویداد
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
توسعهدهنده اشاره کرده بود که این کلاس رویدادهای پنجره را مدیریت خواهد کرد. متد processWindowEvent این وظیفه را انجام میدهد. این متد با ارسال رویداد دریافتشده WindowEvent به کلاس والد خود (JFrame) آغاز میشود؛ اگر این رویداد همان رویداد WINDOW_CLOSING باشد که با کلیک روی دکمه بستن پنجره ایجاد میشود، برنامه خاتمه مییابد.
5.2.2.2.5. نتیجهگیری
کد کلاس پنجره با آنچه در مثال ابتدای فصل نشان داده شده متفاوت است. اگر ما از یک تولیدکننده کد جاوا به غیر از JBuilder استفاده کنیم، بدون شک با کدی کاملاً متفاوت روبرو خواهیم شد. در عمل، ما کد تولیدشده توسط JBuilder را برای ساخت پنجره میپذیریم تا بتوانیم تمام تمرکز خود را بر نوشتن رویدادپردازها برای رابط کاربری گرافیکی معطوف کنیم.
5.2.3. طراحی یک رابط کاربری گرافیکی
5.2.3.1. یک مثال
در مثال قبلی، ما هیچ کامپوننتی را در پنجره قرار ندادیم. اکنون بیایید یک پنجره با یک دکمه، یک برچسب و یک فیلد ورودی بسازیم:

میدانها به شرح زیر هستند:
خیر. | name | نوع | نقش |
1 | lblSaisie | JLabel | یک توضیح |
2 | txtSaisie | JTextField | یک فیلد ورودی |
3 | cmdAfficher | JButton | برای نمایش محتویات فیلد ورودی در یک کادر محاورهای txtSaisie |
طبق همان رویهای که برای پروژه قبلی انجام شد، پروژه interface2.jpr را ایجاد کنید، اما فعلاً هیچ کامپوننتی به پنجره اضافه نکنید.

در پنجره بالا، کلاس interface2.java را از پنجره انتخاب کنید. در سمت راست این پنجره یک پوشه زبانه دار وجود دارد:

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

این | نماینده پنجره است |
contentPane | ظرفی که اجزا در آن قرار میگیرند، و همچنین چیدمان این اجزا در داخل ظرف (BorderLayout بهصورت پیشفرض) |
borderLayout1 | یک نمونه از مدیر چیدمان |
شیء this را انتخاب کنید. پنجرهٔ ویژگیهای آن سپس در سمت راست ظاهر میشود:

برخی از این ویژگیها قابل توجه هستند:
پسزمینه | برای تنظیم رنگ پسزمینه پنجره |
foreground | برای تنظیم رنگ گرافیکها در پنجره |
JMenuBar | برای مرتبط کردن یک منو با پنجره |
عنوان | برای دادن عنوان به پنجره |
قابل تغییر اندازه | برای تنظیم نوع پنجره |
فونت | برای تنظیم قلم متن نمایشدادهشده در پنجره |
در حالی که شیء this هنوز انتخاب شده است، میتوانید با کشیدن نقاط لنگردار اطراف کانتینر، اندازهٔ آن را در صفحه نمایش تغییر دهید:

اکنون آماده هستیم تا کامپوننتها را در کانتینر بالا قرار دهیم. قبل از انجام این کار، مدیر چیدمان را تغییر میدهیم. در پنجره ساختار، شیء contentPane را انتخاب کنید:

سپس، در پنجرهٔ ویژگیهای این شیء، ویژگی layout را انتخاب کرده و مقدار null را از میان گزینههای موجود برگزینید:

عدم وجود مدیر چیدمان به ما اجازه میدهد تا اجزا را آزادانه در داخل کانتینر قرار دهیم. اکنون زمان انتخاب آنهاست.
هنگامی که پنل Conception انتخاب میشود، کامپوننتها در یک پوشهٔ برگهای در بالای پنجرهٔ طراحی در دسترس قرار میگیرند:

برای ساخت رابط کاربری گرافیکی، ما کامپوننتهای swing (1) و کامپوننتهای awt (2) را داریم. در اینجا، از کامپوننتهای swing استفاده خواهیم کرد. از نوار کامپوننت در بالا، یک کامپوننت JLabel (۳)، یک کامپوننت JTextField (۴) و یک کامپوننت JButton (۵) را انتخاب کرده و آنها را در کانتینر پنجره طراحی قرار دهید.

اکنون بیایید هر یک از این سه مؤلفه را سفارشی کنیم:
- برچسب (JLabel) jLabel1
برای باز کردن پنجرهٔ ویژگیها، مؤلفه را انتخاب کنید. در این پنجره، ویژگیهای زیر را تغییر دهید: name: lblSaisie text: Input
- میدان ورودی (JTextField) jTextfield1
کامپوننت را برای باز کردن پنجرهٔ ویژگیهای آن انتخاب کنید. در این پنجره، ویژگیهای زیر را اصلاح کنید: name: txtSaisie, text: خالی بگذارید
- دکمه (JButton): name: cmdAfficher, text: نمایش
اکنون پنجره زیر را داریم:

و ساختار زیر:

میتوانیم پروژه (F9) را اجرا کنیم تا پیشنمایش اولیهای از پنجره در عمل مشاهده کنیم:

پنجره را ببندید. اکنون باید رویهٔ مربوط به کلیک روی دکمهٔ Afficher را بنویسیم. دکمه را انتخاب کنید تا به پنجرهٔ ویژگیهای آن دسترسی پیدا کنید. این پنجره دو زبانه دارد: propriétés و événements. événements را انتخاب کنید.

ستون سمت چپ پنجره، رویدادهای ممکن برای دکمه را فهرست میکند. کلیک کردن روی یک دکمه با رویداد actionPerformed مطابقت دارد. ستون سمت راست حاوی نام رویهای است که هنگام وقوع رویداد مربوطه فراخوانی میشود. روی سلول سمت راست رویداد actionPerformed کلیک کنید:

JBuilder برای هر رویدادپرداز یک نام پیشفرض در قالب nomComposant_nomEvénement تولید میکند – در این مورد، cmdAfficher_actionPerformed. میتوانید نام پیشفرض را حذف کرده و نام دیگری وارد کنید. برای دسترسی به کد دستگیرکننده cmdAfficher_actionPerformed، کافی است روی نام آن در بالا دوبار کلیک کنید. این کار بهطور خودکار شما را به پنجره منبع کلاس میبرد که روی اسکلت کد دستگیرکننده رویداد قرار دارد:
تنها کاری که باقی مانده تکمیل این کد است. در اینجا، میخواهیم یک کادر محاورهای را نمایش دهیم که حاوی محتویات فیلد txtSaisie است:
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(),
"Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
JOptionPane یک کلاس در کتابخانه javax.swing است. این کلاس امکان نمایش پیامها در کنار یک آیکون یا درخواست اطلاعات از کاربر را فراهم میکند. در اینجا، ما از یک متد استاتیک این کلاس استفاده میکنیم:

parentComponent | شیء محفظهٔ «والد» (parent) کادر گفتگو: در این مورد، this. |
پیام | یک شیء برای نمایش. در اینجا، محتوای فیلد ورودی |
عنوان | عنوان کادر گفتگو |
messageType | نوع پیامی که باید نمایش داده شود. آیکونی را که در کادر کنار پیام نمایش داده میشود، تعیین میکند. مقادیر ممکن: INFORMATION_MESSAGE, QUESTION_MESSAGE, ERROR_MESSAGE, WARNING_MESSAGE, PLAIN_MESSAGE |
بیایید اپلیکیشن خود را اجرا کنیم (F9):


5.2.3.2. کد کلاس پنجره
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import javax.swing.event.*;
public class interface2 extends JFrame {
JPanel contentPane;
JLabel lblSaisie = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmdAfficher = new JButton();
/**ساخت فریم*/
public interface2() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی کامپوننت*/
private void jbInit() throws Exception {
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}
/**جایگزین شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(), "Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
}
5.2.3.2.1. ویژگیها
ظرف برای اجزای نوع JPanel و سه جزء موجود هستند.
5.2.3.2.2. تولیدکننده
/**ساخت فریم*/
public interface2() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی کامپوننت*/
private void jbInit() throws Exception {
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}
سازنده interface2 مشابه سازنده رابط کاربری گرافیکی قبلی است که بررسی کردیم. تفاوتها در متد jbInit نهفته است: کد ساخت پنجره به کامپوننتهای قرار گرفته درون آن بستگی دارد. میتوانیم کد jbInit را مجدداً استفاده کنیم و نظرات خود را اضافه کنیم:
private void jbInit() throws Exception {
// خود پنجره (اندازه، عنوان)
this.setSize(new Dimension(304, 129));
this.setTitle("Saisies & boutons - 1");
// کانتینر کامپوننت
contentPane = (JPanel) this.getContentPane();
// هیچ مدیر چیدمانی برای این کانتینر وجود ندارد
contentPane.setLayout(null);
// برچسب lblSaisie (متن، موقعیت، اندازه)
lblSaisie.setText("Saisie");
lblSaisie.setBounds(new Rectangle(25, 23, 71, 21));
// میدان ورودی (موقعیت، اندازه)
txtSaisie.setBounds(new Rectangle(120, 21, 138, 24));
// دکمه «نمایش» (برچسب، موقعیت، اندازه)
cmdAfficher.setText("Afficher");
cmdAfficher.setBounds(new Rectangle(111, 77, 77, 20));
// پردازشگر رویداد دکمه
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
// افزودن ۳ مؤلفه به کانتینر
contentPane.add(lblSaisie, null);
contentPane.add(txtSaisie, null);
contentPane.add(cmdAfficher, null);
}//jbInit
دو نکته قابل توجه است:
- این کد میتوانست بهصورت دستی نوشته شود. این بدان معناست که JBuilder برای ساخت یک رابط کاربری گرافیکی ضروری نیست.
- نحوهٔ تعیین رویدادپرداز برای دکمهٔ cmdAfficher. رویدادپرداز برای کامپوننت cmdAfficher میتوانست به صورت cmdAfficher.addActionListener اعلام شود.(new handler()) که در آن gestionnaire کلاسی با متد عمومی actionPerformed خواهد بود که مسئول رسیدگی به کلیکهای روی دکمه Afficher است. در اینجا، JBuilder از یک نمونه از یک کلاس ناشناس به عنوان دستگیرکننده استفاده میکند:
new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
یک نمونه جدید از رابط ActionListener ایجاد میشود و متد actionPerformed آن همزمان تعریف میگردد. این متد به سادگی یک متد از کلاس interface2 را فراخوانی میکند. تمام اینها صرفاً یک راهحل موقت است تا در همان کلاسی که پنجره در آن تعریف شده، رویههای مدیریت رویدادهای اجزای آن پنجره را تعریف کند. میتوان به روش دیگری عمل کرد:
که یعنی متد actionPerformed در this، یعنی در کلاس پنجره، جستجو خواهد شد. این متد دوم سادهتر به نظر میرسد، اما متد اول یک مزیت نسبت به آن دارد: این امکان را میدهد که برای دکمههای مختلف از هندلرهای متفاوتی استفاده شود، در حالی که متد دوم این امکان را ندارد. در مورد دوم، یک متد واحد actionPeformed باید کلیک روی دکمههای مختلف را مدیریت کند و بنابراین باید ابتدا تشخیص دهد که کدام دکمه رویداد را فعال کرده است، پیش از آنکه بتواند پردازش را آغاز کند.
5.2.3.2.3. پردازندههای رویداد
اینها همانهایی هستند که قبلاً بررسی کردهایم:
/**جایگزین شده، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
// کلیک روی دکمه «Show»
void cmdAfficher_actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "texte saisi="+txtSaisie.getText(), "Vérification de la saisie",JOptionPane.INFORMATION_MESSAGE);
}
5.2.3.3. Conclusion
از دو پروژه مورد مطالعه، میتوان نتیجه گرفت که پس از ساخت رابط کاربری گرافیکی با استفاده از JBuilder، وظیفه توسعهدهنده نوشتن رویدادپردازها برای رویدادهایی است که میخواهد برای آن رابط کاربری گرافیکی مدیریت کند.
5.2.4. درخواست کمک
در جاوا، اغلب به کمک نیاز دارید، بهویژه به دلیل تعداد بسیار زیاد کلاسهای موجود. در اینجا چند نکته برای یافتن کمک در مورد یک کلاس آورده شده است. از منو گزینه Help/Help Topics را انتخاب کنید.

صفحه کمک معمولاً دو پنجره دارد:
- یکی در سمت چپ که در آن عبارت مورد نظر خود را وارد میکنید. این پنجره سه زبانه دارد: Sommaire، Index و Chercher.
- پنجره سمت راست که نتایج جستجو را نمایش میدهد
راهنما در مورد نحوه استفاده از سیستم راهنمای JBuilder در دسترس است. در راهنمای JBuilder، گزینه Help/Using Help را انتخاب کنید. این بخش نحوه استفاده از سیستم راهنما را توضیح میدهد. برای مثال، اجزای مختلف نمایشگر راهنما را به شما نشان خواهد داد:

بیایید نگاهی دقیقتر به صفحات Sommaire و Index بیندازیم.
5.2.4.1. راهنما: فهرست مطالب

5.2.4.1.1. فهرست مطالب: مقدمهای بر جاوا
در اینجا اصول اولیهٔ جاوا را خواهید یافت، اما نه تنها آن، همانطور که از فهرست موضوعات پوششدادهشده در این ماژول پیداست:

5.2.4.1.2. فهرست: آموزشها
اگر گزینه «آموزشها» را از فهرست مطالب بالا انتخاب کنیم، پنجره سمت راست فهرستی از آموزشهای موجود را نمایش میدهد:

آموزشهای پایه بهویژه برای تسلط بر JBuilder بسیار مفید هستند. آموزشهای بسیاری غیر از موارد نمایشدادهشده در بالا وجود دارد، و هنگامی که میخواهید یک برنامه کاربردی توسعه دهید، ممکن است ارزش داشته باشد که ابتدا بررسی کنید آیا آموزشی وجود دارد که بتواند به شما کمک کند.
5.2.4.1.3. فهرست: JDK
با انتخاب گزینه Java 2 JDK 1.3، به تمام کتابخانههای موجود در JDK دسترسی خواهید داشت. بهطور کلی، اگر به دنبال اطلاعاتی درباره یک کلاس خاص هستید و نمیدانید در کدام کتابخانه قرار دارد، اینجا جای مناسبی نیست. با این حال، این گزینه زمانی مفید است که میخواهید دید کلی از کتابخانههای جاوا به دست آورید.
5.2.4.2. راهنما: نمایه
در پنل سمت چپ پنجرهٔ راهنما، زبانهٔ «فهرست» را انتخاب کنید. این گزینه به شما امکان میدهد، برای مثال، راهنمای یک کلاس را پیدا کنید. فرض کنید میخواهید دربارهٔ متدهای فیلدهای ورودی swing و JTextField اطلاعات کسب کنید. JTextField را در کادر متن جستجو تایپ کنید:
![]()
تابع راهنما ورودیهای شاخص را که با متنی که وارد کردهاید شروع میشوند، بازخواهد گرداند:

کافی است روی مدخلی که به آن علاقهمند هستید، در این مورد کلاس JTextField، دوبار کلیک کنید. راهنمای این کلاس سپس در پنجره سمت راست نمایش داده خواهد شد:

سپس توضیح کاملی از کلاس ارائه میشود.
5.2.5. برخی از کامپوننتهای Swing
اکنون به بررسی برنامههای مختلفی میپردازیم که شامل رایجترین اجزای swing هستند، تا روشها و ویژگیهای اصلی آنها را کشف کنیم. برای هر برنامه، رابط کاربری گرافیکی و کد مربوطه، بهویژه کد دستگیرکنندههای رویداد، را ارائه خواهیم داد.
5.2.5.1. کامپوننتهای JLabel و JTextField
ما قبلاً با این دو کامپوننت آشنا شدهایم. JLabel یک کامپوننت متنی است و JTextField یک کامپوننت فیلد ورودی است. دو متد اصلی آنها عبارتند از
String getText() | برای بازیابی محتوای فیلد ورودی یا متن برچسب |
void setText(String unTexte) | برای تنظیم unTexte در فیلد یا برچسب |
رویدادهای معمولاً استفاده شده برای JTextField به شرح زیر است:
actionPerformed | نشان میدهد که کاربر (با فشردن Enter) متن وارد شده را تأیید کرده است |
caretUpdate | نشان میدهد که کاربر مکاننما را جابهجا کرده است |
inputMethodChanged | نشان میدهد که کاربر فیلد ورودی را تغییر داده است |
در اینجا مثالی آورده شده است که از رویداد caretUpdate برای ردیابی تغییرات یک فیلد ورودی استفاده میکند:

خیر. | نوع | نام | نقش |
1 | JTextField | txtSaisie | میدان ورودی |
2 | JTextField | txtControle | متن ۱ را بهصورت بلادرنگ نمایش میدهد |
۳ | JButton | cmdEffacer | برای پاک کردن فیلدهای ۱ و ۲ |
4 | JButton | cmdQuitter | برای خروج از برنامه |
کد مربوطه برای این برنامه به شرح زیر است:
import java.awt.*;
....
public class Cadre1 extends JFrame {
JPanel contentPane;
JTextField txtSaisie = new JTextField();
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JTextField txtControle = new JTextField();
JButton CmdEffacer = new JButton();
JButton CmdQuitter = new JButton();
/**چارچوب را بسازید*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی کامپوننت*/
private void jbInit() throws Exception {
....
txtSaisie.addCaretListener(new javax.swing.event.CaretListener() {
public void caretUpdate(CaretEvent e) {
txtSaisie_caretUpdate(e);
}
});
...
CmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
CmdEffacer_actionPerformed(e);
}
});
...
CmdQuitter.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
CmdQuitter_actionPerformed(e);
}
});
....
}
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_caretUpdate(CaretEvent e) {
// نشانگر ورودی جابجا شده است
txtControle.setText(txtSaisie.getText());
}
void CmdQuitter_actionPerformed(ActionEvent e) {
//خروج از برنامه
System.exit(0);
}
void CmdEffacer_actionPerformed(ActionEvent e) {
// پاک کردن محتویات فیلد ورودی
txtSaisie.setText("");
}
}
در اینجا نمونهای از خروجی آورده شده است:

5.2.5.2. کامپوننت JComboBox


یک کامپوننت JComboBox یک لیست کشویی است که با یک فیلد ورودی ترکیب شده است: کاربر میتواند یا یک مورد را از (2) انتخاب کند یا متن را در (1) تایپ کند. به طور پیشفرض، کامپوننتهای JComboBox قابل ویرایش نیستند. برای قابل ویرایش کردن آنها، باید صراحتاً متد setEditable(true) را فراخوانی کنید. برای کسب اطلاعات بیشتر درباره کلاس JComboBox، عبارت JComboBox را در نمایه راهنما تایپ کنید.
شیء JComboBox را میتوان به روشهای مختلفی ایجاد کرد:
new JComboBox() | یک کادر ترکیبی خالی ایجاد میکند |
new JComboBox (Object[] items) | یک کادر ترکیبی حاوی آرایهای از اشیاء ایجاد میکند |
new JComboBox(Vector items) | همانند مورد بالا، اما با یک بردار از اشیاء |
شاید تعجبآور باشد که یک کادر ترکیبی میتواند اشیاء را در خود جای دهد، در حالی که معمولاً حاوی رشتهها است. از نظر بصری، این امر واقعاً صادق است. اگر یک JComboBox حاوی یک شیء obj باشد، رشته obj.toString را نمایش میدهد(). به یاد داشته باشید که هر شیء دارای متد toString است که از کلاس Object به ارث رسیده و یک رشتهٔ کاراکتری را بازمیگرداند که «نماینده» آن شیء است.
متدهای مفید کلاس JCombobox به شرح زیر هستند:
void addItem(Object unObjet) | یک شیء را به لیست کشویی اضافه میکند |
int getItemCount() | تعداد موارد موجود در کادر ترکیبی را برمیگرداند |
Object getItemAt(int i) | شیء i-ام در کادر ترکیبی را برمیگرداند |
void insertItemAt(Object unObjet, int i) | مقدار unObjet را در موقعیت i در کادر ترکیبی درج میکند |
integer getSelectedIndex() | تعداد آیتم انتخابشده در کادر ترکیبی را برمیگرداند |
شئ getSelectedItem() | شیء انتخابشده در کادر ترکیبی را برمیگرداند |
void setSelectedIndex(int i) | مورد i را از لیست کشویی انتخاب میکند |
void setSelectedItem(Object unObjet) | شیء مشخصشده را از لیست کشویی انتخاب میکند |
void removeAllItems() | کادر ترکیبی را پاک میکند |
void removeItemAt(int i) | مورد شماره i را از لیست کشویی حذف میکند |
void removeItem(Object unObjet) | شیء مشخصشده را از کادر ترکیبی حذف میکند |
void setEditable(boolean val) | کادر ترکیبی را قابل ویرایش (val=true) یا غیرقابل ویرایش (val=false) تنظیم میکند |
هنگامی که یک آیتم از لیست کشویی انتخاب میشود، رویداد actionPerformed فعال میشود که میتوان از آن برای اطلاع از تغییر در انتخاب داخل کادر ترکیبی استفاده کرد. در برنامه زیر، ما از این رویداد برای نمایش آیتمی که از لیست انتخاب شده است، استفاده میکنیم.

ما فقط کد مرتبط با پنجره را نمایش میدهیم.
public class Cadre1 extends JFrame {
JPanel contentPane;
JComboBox jComboBox1 = new JComboBox();
JLabel jLabel1 = new JLabel();
/**فرم را بسازید*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
//پردازش – پر کردن لیست کشویی
String[] infos={"un","deux","trois","quatre"};
for(int i=0;i<infos.length;i++)
jComboBox1.addItem(infos[i]);
}
/**کامپوننت را راهاندازی کنید*/
private void jbInit() throws Exception {
....
jComboBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jComboBox1_actionPerformed(e);
}
});
....
}
void jComboBox1_actionPerformed(ActionEvent e) {
//یک آیتم جدید انتخاب شده است – آن را نمایش دهید
JOptionPane.showMessageDialog(this,jComboBox1.getSelectedItem(),
"actionPerformed",JOptionPane.INFORMATION_MESSAGE);
}
}
5.2.5.3. کامپوننت JList
کامپوننت Swing JList پیچیدهتر از معادل خود در کتابخانه، awt است. دو تفاوت مهم وجود دارد:
- محتوای لیست توسط ابجکت متفاوتی از خود لیست مدیریت میشود. در اینجا از یک شیء DefaultListModel استفاده خواهیم کرد که همانند Vector عمل میکند، اما همچنین به محض تغییر محتوای خود، شیء JList را مطلع میسازد تا نمایش بصری لیست نیز متناسب با آن تغییر کند.
- فهرست بهطور پیشفرض پیمایش نمیشود. شما باید فهرست را در یک کانتینر ScrollPane قرار دهید تا پیمایش فعال شود.
در کد منبع، یک لیست میتواند به صورت زیر تعریف شود:
// آرایه مقادیر در لیست
DefaultlistModel valeurs=new DefaultListModel();
//خود لیست، که بردار مقادیر آن به آن مرتبط است
JList jList1 = new JList(valeurs);
// کانتینر پیمایشی که لیست در آن قرار میگیرد تا یک لیست پیمایشی ایجاد شود
JScrollPane jScrollPane1 = new JScrollPane(jList1);
برای درج لیست jList1 در کانتینر jScrollPane1، کدی که توسط JBuilder تولید میشود به شیوهای متفاوت عمل میکند:
- اعلام کانتینر در ویژگیهای پنجره
- سپس، در کد مربوط به jbInit، لیست با کانتینر مرتبط میشود
برای افزودن مقادیر به لیست JList1 بالا، کافی است آنها را به بردار مقدار آن valeurs اضافه کنید:
و سپس پنجره زیر را مشاهده خواهید کرد:

این رابط چگونه ساخته شده است؟
- یک کامپوننت JScrollPane را از صفحه «Swing containers» در بخش کامپوننتها انتخاب کرده و آن را بکشید و در پنجره رها کنید، سپس ابعاد آن را به اندازه دلخواه تنظیم کنید
- یک کامپوننت JList را از صفحه «Swing» کامپوننتها انتخاب کرده و آن را به داخل کانتینر JScrollPane بکشید و رها کنید، جایی که سپس کل فضا را اشغال خواهد کرد.
کد تولید شده توسط JBuilder نیاز به اصلاح جزئی دارد تا کد زیر تولید شود:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
DefaultListModel valeurs=new DefaultListModel();
JList jList1 = new JList(valeurs);
JScrollPane jScrollPane1 = new JScrollPane();
JLabel jLabel2 = new JLabel();
/**ساخت فریم*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
//پردازش
// فهرست در scrollPane گنجانده شده است
// فهرست اولیه
for(int i=0;i<10;i++)
valeurs.addElement(""+i);
}
/**ابتدا کردن مؤلفه*/
private void jbInit() throws Exception {
....
// فهرست jList1 با کانتینر jcrollPane1 مرتبط است
jScrollPane1.getViewport().add(jList1, null);
}
/**جایگزین شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
....
}
}
بیایید اکنون با جستجو برای JList در نمایهی راهنما، روشهای اصلی کلاس JList را بررسی کنیم. شیء JList را میتوان به روشهای مختلفی ایجاد کرد:

یک روش ساده همان روشی است که ما استفاده کردهایم: ایجاد یک V خالی از نوع DefaultListModel و سپس مرتبط کردن آن با لیست مورد نظر با استفاده از new JList(V). محتوای لیست توسط شی JList مدیریت نمیشود، بلکه توسط شیای که مقادیر لیست را در خود دارد، مدیریت میشود. اگر محتوا با استفاده از یک شیء DefaultListModel مبتنی بر کلاس Vector ساخته شده باشد، میتوان از متدهای کلاس Vector برای افزودن، درج و حذف موارد از لیست استفاده کرد. یک لیست میتواند تکانتخابی یا چندانتخابی باشد. این توسط متد setSelectionMode تعیین میشود:

میتوان حالت انتخاب فعلی را با استفاده از getSelectionMode تعیین کرد:
![]()
موارد انتخابشده را میتوان با استفاده از روشهای زیر بازیابی کرد:

ما میتوانیم با استفاده از سازنده JList(DefaultListModel)، یک بردار از مقادیر را به یک لیست مرتبط کنیم. برعکس، ما میتوانیم با استفاده از: شیء DefaultListModel را از یک لیست JList به دست آوریم.

اکنون اطلاعات کافی برای نوشتن برنامه زیر را داریم:

اجزای این پنجره به شرح زیر است:
خیر. | نوع | name | نقش |
1 | JTextField | txtSaisie | میدان ورودی |
2 | JList | jList1 | لیست قرار گرفته در داخل یک کانتینر jScrollPane1 |
3 | JList | jList2 | فهرست موجود در یک کانتینر jScrollPane2 |
4 | JButton | cmd1To2 | موارد انتخابشده را از لیست ۱ به لیست ۲ منتقل میکند |
5 | JButton | cmd2To1 | معکوس آن را انجام میدهد |
۶ | JButton | cmdRaz1 | فهرست 1 را پاک کنید |
7 | JButton | cmdRaz2 | پاک کردن لیست ۲ |
کاربر متن را در فیلد (1) تایپ کرده و آن را ارسال میکند. این کار رویداد actionPerformed را در فیلد ورودی فعال میکند که برای افزودن متن واردشده به فهرست 1 استفاده میشود. در اینجا کد مورد نیاز برای این اولین تابع آمده است:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**ساخت فریم*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**اجرای اولیهٔ کامپوننت*/
private void jbInit() throws Exception {
...
txtSaisie.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtSaisie_actionPerformed(e);
}
});
...
// Jlist1 در کانتینر jScrollPane1 قرار میگیرد
jScrollPane1.getViewport().add(jList1, null);
//Jlist2 در کانتینر jScrollPane2 قرار داده شده است
jScrollPane2.getViewport().add(jList2, null);
...
}
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_actionPerformed(ActionEvent e) {
//متن واردشده اعتبارسنجی شده است
// متن وارد شده با حذف فاصلههای ابتدایی و انتهایی بازیابی میشود
String texte=txtSaisie.getText().trim();
// اگر خالی باشد، آن را نمیخواهیم
if(texte.equals("")){
// پیام خطا
JOptionPane.showMessageDialog(this,"Vous devez taper un texte",
"Erreur",JOptionPane.WARNING_MESSAGE);
// پایان
return;
}//اگر
// اگر خالی نباشد، آن را به مقادیر در لیست 1 اضافه کنید
v1.addElement(texte);
// و فیلد ورودی را پاک کنید
txtSaisie.setText("");
}/// txtSaisie_actionperformed
}//کلاس
کد برای انتقال موارد انتخابشده از یک لیست به لیست دیگر به شرح زیر است:
void cmd1To2_actionPerformed(ActionEvent e) {
//موارد منتخب را از فهرست ۱ به فهرست ۲ منتقل کنید
transfert(jList1,jList2);
}//cmd1To2
void cmd2To1_actionPerformed(ActionEvent e) {
//انتقال موارد منتخب از jList2 به jList1
transfert(jList2,jList1);
}//cmd2TO1
private void transfert(JList L1, JList L2){
//انتقال موارد منتخب از لیست ۱ به لیست ۲
//آرایهٔ شاخصهای موارد انتخابشده را از L1 بازیابی کنید
int[] indices=L1.getSelectedIndices();
// آیا کاری با آن دارد؟
if (indices.length==0) return;
//مقادیر را از L1 بازیابی میکند
DefaultListModel v1=(DefaultListModel)L1.getModel();
//و آنهایی از L2
DefaultListModel v2=(DefaultListModel)L2.getModel();
for(int i=indices.length-1;i>=0;i--){
// ما مقادیر انتخابشده از L1 را به L2 اضافه میکنیم
v2.addElement(v1.elementAt(indices[i]));
// عناصر از L1 که به L2 کپی شدهاند باید از L1 حذف شوند
v1.removeElementAt(indices[i]);
}//برای
}//انتقال
کد مرتبط با دکمههای Raz بسیار ساده است:
void cmdRaz1_actionPerformed(ActionEvent e) {
// فهرست ۱ را پاک کنید
v1.removeAllElements();
}//فرمان Raz1
void cmdRaz2_actionPerformed(ActionEvent e) {
// فهرست ۲ را پاک کنید
v2.removeAllElements();
}///cmd Raz2
5.2.5.4. تیکباکسهای JCheckBox، دکمههای رادیویی JButtonRadio
ما پیشنهاد میکنیم برنامه زیر را بنویسیم:

اجزای پنجره به شرح زیر هستند:
خیر. | نوع | نام | نقش |
1 | JButtonRadio | jButtonRadio1 jButtonRadio2 jButtonRadio3 | ۳ دکمهٔ رادیویی متعلق به گروه buttonGroup1 |
۲ | JCheckBox | jCheckBox1 jCheckBox2 jCheckBox3 | ۳ کادر تیکدار |
۳ | JList | jList1 | یک لیست درون یک کانتینر jScrollPane1 |
۴ | ButtonGroup | buttonGroup1 | جزء غیرقابل مشاهده – برای گروهبندی سه دکمه رادیویی استفاده میشود تا وقتی یکی انتخاب میشود، بقیه غیرفعال شوند. |
یک گروه از دکمههای رادیویی را میتوان به صورت زیر ایجاد کرد:
- هر دکمه رادیویی را بدون نگرانی در مورد گروهبندی آنها قرار دهید
- یک کامپوننت Swing به نام ButtonGroup را داخل کانتینر قرار دهید. این کامپوننت غیرقابل مشاهده است. بنابراین در ویزور دیزاینر پنجره نمایش داده نمیشود. با این حال، در ساختار پنجره ظاهر میشود:

همانطور که در بالا در شاخه Autre نشان داده شده است، اینها ویژگیهای غیرنمایشی پنجره هستند. پس از ایجاد یک گروه از دکمه های رادیویی، هر دکمه رادیویی را میتوان به آن مرتبط کرد. برای این کار، ویژگیهای دکمه رادیویی را انتخاب کنید:

و در ویژگی buttonGroup دکمه رادیویی، نام گروهی را که میخواهید دکمه رادیویی را به آن اختصاص دهید وارد کنید—در این مورد، buttonGroup1. این فرآیند را برای هر سه دکمه رادیویی تکرار کنید.
روش اصلی برای دکمههای رادیویی و چکباکسها، متد isSelected() است که نشان میدهد آیا چکباکس یا دکمه رادیویی انتخاب شده است. متن مرتبط با کامپوننت را میتوان با استفاده از getText() بازیابی کرد و با استفاده از setText تنظیم نمود.(String unTexte). دکمهٔ رادیویی یا تیکباکس را میتوان با استفاده از متد setSelected(boolean value) انتخاب کرد.
وقتی دکمه رادیویی یا تیکباکس کلیک میشود، رویداد actionPerformed فعال میشود. در کد زیر، از این رویداد برای ردیابی تغییرات در مقادیر دکمههای رادیویی و تیکباکسها استفاده میکنیم:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JRadioButton jRadioButton1 = new JRadioButton();
JRadioButton jRadioButton2 = new JRadioButton();
JRadioButton jRadioButton3 = new JRadioButton();
JCheckBox jCheckBox1 = new JCheckBox();
JCheckBox jCheckBox2 = new JCheckBox();
JCheckBox jCheckBox3 = new JCheckBox();
ButtonGroup buttonGroup1 = new ButtonGroup();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel valeurs=new DefaultListModel();
JList jList1 = new JList(valeurs);
/**ساخت فریم*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
jRadioButton1.setSelected(true);
jRadioButton1.setText("un");
jRadioButton1.setBounds(new Rectangle(57, 31, 49, 23));
jRadioButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton2.setBounds(new Rectangle(113, 30, 49, 23));
jRadioButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton2.setText("deux");
jRadioButton3.setBounds(new Rectangle(168, 30, 49, 23));
jRadioButton3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheRadioButtons(e);
}
});
jRadioButton3.setText("trois");
//دکمههای رادیویی گروهبندی شدهاند
buttonGroup1.add(jRadioButton1);
buttonGroup1.add(jRadioButton2);
buttonGroup1.add(jRadioButton3);
// تیکباکسها
jCheckBox1.setText("A");
jCheckBox1.setBounds(new Rectangle(58, 69, 32, 17));
jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
jCheckBox2.setBounds(new Rectangle(112, 69, 40, 17));
jCheckBox2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
jCheckBox2.setText("B");
jCheckBox3.setText("C");
jCheckBox3.setBounds(new Rectangle(170, 69, 37, 17));
jCheckBox3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
afficheCases(e);
}
});
....
}
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
...
}
private void afficheRadioButtons(ActionEvent e){
//مقادیر ۳ دکمه رادیویی را نمایش میدهد
valeurs.addElement("boutons radio=("+jRadioButton1.isSelected()+","+
jRadioButton2.isSelected()+","+jRadioButton3.isSelected()+")");
}//afficheRadioButtons
void afficheCases(ActionEvent e) {
//مقادیر چکباکسها را نمایش میدهد
valeurs.addElement("cases à cocher=["+jCheckBox1.isSelected()+","+
jCheckBox2.isSelected()+","+jCheckBox3.isSelected()+")");
}//afficheCases
}//مرتبسازی
در اینجا نمونهای از خروجی آورده شده است:

5.2.5.5. کامپوننت JScrollBar
بیایید اپلیکیشن زیر را ایجاد کنیم:

خیر. | نوع | نام | نقش |
1 | JScrollBar | jScrollBar1 | یک واریاتور افقی |
2 | JScrollBar | jScrollBar2 | یک واریاتور عمودی |
۳ | JTextField | txtvaleurHS | مقدار درایو افقی ۱ را نمایش میدهد – همچنین امکان تنظیم این مقدار را فراهم میکند |
۴ | JTextField | txtvaleurVS | مقدار اسلایدر عمودی ۲ را نمایش میدهد – همچنین امکان تنظیم این مقدار را فراهم میکند |
- اسلایدر JScrollBar به کاربر اجازه میدهد از میان بازهای از مقادیر صحیح، مقداری را انتخاب کند که با «باند» اسلایدر نشان داده میشود و نشانگر روی آن حرکت میکند.
- برای یک اسلایدر افقی، انتهای سمت چپ نشاندهنده حداقل مقدار محدوده، انتهای سمت راست نشاندهنده حداکثر مقدار و مکاننما نشاندهنده مقدار انتخابشده فعلی است. برای یک اسلایدر عمودی، حداقل مقدار با انتهای بالایی و حداکثر مقدار با انتهای پایینی نشان داده میشود. زوج (min,max) به صورت پیشفرض روی (0,100) تنظیم شده است.
- کلیک کردن روی انتهای اسلایدر، مقدار را به اندازه یک گام (مثبت یا منفی) بسته به انتهای کلیک شده تغییر میدهد، که به آن unitIncrement گفته میشود و به طور پیشفرض روی 1 تنظیم شده است.
- کلیک کردن در هر دو طرف اسلایدر، بسته به اینکه کدام انتها کلیک شود، مقدار را به اندازه یک گام (مثبت یا منفی) تغییر میدهد، که به آن blockIncrement گفته میشود و به طور پیشفرض روی 10 تنظیم شده است.
- این پنج مقدار (min, max, value, unitIncrement, blockIncrement) را میتوان با استفاده از متدهای getMinimum(), getMaximum(), به دست آورد. getValue()، getUnitIncrement()، getBlockIncrement()، که همگی یک عدد صحیح بازمیگردانند و میتوان آنها را با متدهای setMinimum(int min) مقداردهی کرد، setMaximum(int max), setValue(int val), setUnitIncrement(int uInc), setBlockIncrement(int bInc)
چند نکته وجود دارد که هنگام استفاده از کامپوننتهای JScrollBar باید در نظر گرفت. اول اینکه، میتوان آن را در نوار کامپوننت Swing یافت:

وقتی آن را به داخل کانتینر میکشید و رها میکنید، بهطور پیشفرض عمودی است. میتوانید با استفاده از ویژگی orientation زیر آن را افقی کنید:

در برگهٔ ویژگیها در بالا، میتوانیم ببینیم که به ویژگیهای minimum، maximum، value دسترسی داریم، unitIncrement، blockIncrement از JScrollbar. بنابراین میتوانیم اینها را در زمان طراحی تنظیم کنیم. وقتی یک نوار پیمایش روی کانتینر قرار میگیرد، «دامنه پیمایش» آن ظاهر نمیشود:

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

در اینجا مثالی از شکل RaisedBevel آورده شده است:
![]()
وقتی روی انتهای بالایی یک اسلایدر عمودی کلیک میکنید، مقدار آن کاهش مییابد. این موضوع ممکن است کاربر عادی را غافلگیر کند، زیرا او معمولاً انتظار دارد مقدار «افزایش» یابد. این مشکل با تنظیم مقادیر unitIncrement و blockIncrement به مقادیر منفی حل میشود.
چگونه میتوانید تغییرات یک اسلایدر را نظارت کنید؟ هنگامی که مقدار آن تغییر میکند، رویداد adjustmentValueChanged فعال میشود. به سادگی یک رویه را به این رویداد مرتبط کنید تا از هر تغییر در مقدار اسلایدر مطلع شوید.

کد مربوطه برای برنامه ما به شرح زیر است:
....
public class cadreAppli extends JFrame {
JPanel contentPane;
JScrollBar jScrollBar1 = new JScrollBar();
Border border1;
JTextField txtValeurHS = new JTextField();
JScrollBar jScrollBar2 = new JScrollBar();
JTextField txtValeurVS = new JTextField();
TitledBorder titledBorder1;
/**ساخت فریم*/
public cadreAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
...
// یک مرز برای نوارهای پیمایش
border1 = BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.white,Color.white,new Color(134, 134, 134),new Color(93, 93, 93));
// بدون نوار عنوان یا حاشیه
titledBorder1 = new TitledBorder("");
jScrollBar1.setOrientation(JScrollBar.HORIZONTAL);
jScrollBar1.setBorder(BorderFactory.createRaisedBevelBorder());
jScrollBar1.setAutoscrolls(true);
jScrollBar1.setBounds(new Rectangle(37, 17, 218, 20));
jScrollBar1.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
jScrollBar1_adjustmentValueChanged(e);
}
});
txtValeurHS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtValeurHS_actionPerformed(e);
}
});
jScrollBar2.setBounds(new Rectangle(39, 51, 30, 27));
jScrollBar2.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(AdjustmentEvent e) {
jScrollBar2_adjustmentValueChanged(e);
}
});
jScrollBar2.setAutoscrolls(true);
jScrollBar2.setUnitIncrement(-1);
jScrollBar2.setBorder(BorderFactory.createRaisedBevelBorder());
txtValeurVS.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtValeurVS_actionPerformed(e);
}
});
......
}
/**تعویض شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
...
}
void jScrollBar1_adjustmentValueChanged(AdjustmentEvent e) {
// مقدار نوار پیمایش ۱ تغییر کرده است
txtValeurHS.setText(""+jScrollBar1.getValue());
}
void jScrollBar2_adjustmentValueChanged(AdjustmentEvent e) {
// مقدار نوار پیمایش ۲ تغییر کرده است
txtValeurVS.setText(""+jScrollBar2.getValue());
}
void txtValeurHS_actionPerformed(ActionEvent e) {
//مقدار نوار پیمایش افقی را تنظیم میکند
setValeur(jScrollBar1,txtValeurHS);
}
void txtValeurVS_actionPerformed(ActionEvent e) {
//مقدار نوار پیمایش عمودی را تنظیم میکند
setValeur(jScrollBar2,txtValeurVS);
}
private void setValeur(JScrollBar jS, JTextField jT){
//مقدار نوار پیمایش jS را به متنی که در فیلد jT قرار دارد تنظیم میکند
int valeur=0;
try{
valeur=Integer.parseInt(jT.getText());
jS.setValue(valeur);
}
catch (Exception e){
//خطا را نمایش میدهد
afficher(""+e);
}//try-catch
}//setValeur
void afficher(String message){
//پیامی را در یک کادر نمایش میدهد
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//نمایش
}
در اینجا نمونهای از خروجی آورده شده است:

5.2.5.6. کامپوننت JTextArea
کامپوننت JTextArea به شما امکان میدهد چندین خط متن وارد کنید، برخلاف کامپوننت JTextField که فقط یک خط را مجاز میداند. اگر این کامپوننت در داخل یک کانتینر قابل پیمایش (JScrollPane) قرار گیرد، یک فیلد ورودی متن قابل پیمایش ایجاد میکند. این نوع کامپوننت ممکن است، برای مثال، در یک برنامه ایمیل یافت شود که در آن متن پیام ارسالی در یک کامپوننت JTextArea تایپ میشود. روشهای استاندارد عبارتند از String getText() برای بازیابی محتویات فیلد متن، و setText(String unTexte) برای تنظیم unTexte در فیلد متن، و append(String unTexte) برای الحاق unTexte به متن موجود در فیلد متن. برنامه زیر را در نظر بگیرید:

خیر. | نوع | نام | نقش |
1 | JTextArea | txtTexte | یک کادر متن چندخطی |
2 | JButton | cmdAfficher | محتویات 1 را در یک کادر محاورهای نمایش میدهد |
3 | JButton | cmdEffacer | محتویات 1 را پاک میکند |
4 | JTextField | txtAjout | متن اضافه شده به متن در 1 هنگام تأیید با فشردن کلید Enter. |
۵ | JScrollPane | jScrollPane1 | یک کانتینر پیمایشی که در آن متنجعبهی 1 قرار گرفته است تا یک متنجعبهی پیمایشی ایجاد شود. |
کد مربوطه به شرح زیر است:
.....
public class cadreAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JButton cmdAfficher = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
JTextArea txtTexte = new JTextArea();
JLabel jLabel2 = new JLabel();
JTextField txtAjout = new JTextField();
JButton cmdEffacer = new JButton();
/**ساخت فریم*/
public cadreAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
cmdAfficher.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdAfficher_actionPerformed(e);
}
});
txtAjout.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtAjout_actionPerformed(e);
}
});
cmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdEffacer_actionPerformed(e);
}
});
.......
jScrollPane1.getViewport().add(txtTexte, null);
}
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
........
}
void cmdAfficher_actionPerformed(ActionEvent e) {
//محتویات TextArea را نمایش میدهد
afficher(txtTexte.getText());
}
void afficher(String message){
//یک پیام را در یک کادر نمایش میدهد
JOptionPane.showMessageDialog(this,message,"Suivi",JOptionPane.INFORMATION_MESSAGE);
}//نمایش
void cmdEffacer_actionPerformed(ActionEvent e) {
txtTexte.setText("");
}//cmdEffacer_actionPerformed
void txtAjout_actionPerformed(ActionEvent e) {
// افزودن متن
txtTexte.append(txtAjout.getText());
//پاک کردن و افزودن
txtAjout.setText("");
}//
}
5.2.6. رویدادهای ماوس
هنگام ترسیم در داخل یک کانتینر، دانستن موقعیت ماوس مهم است تا برای مثال، هنگام کلیک روی ماوس بتوان یک نقطه نمایش داد. حرکات ماوس، رویدادهایی را در کانتینری که ماوس در آن در حال حرکت است، فعال میکند. در اینجا، برای مثال، رویدادهایی که توسط JBuilder برای یک کانتینر JPanel ارائه میشوند، آورده شده است:

mouseClicked | کلیک ماوس |
mouseDragged | حرکت ماوس، فشرده شدن دکمه چپ |
mouseEntered | موش به تازگی وارد ناحیه کانتینر شده است |
mouseExited | موش به تازگی سطح ظرف را ترک کرده است |
mouseMoved | موش در حال حرکت است |
mousePressed | دکمه چپ ماوس فشرده شد |
mouseReleased | رها شدن دکمه چپ ماوس |
در اینجا برنامهای برای کمک به شما جهت درک بهتر زمان وقوع رویدادهای مختلف ماوس آورده شده است:

خیر. | نوع | نام | نقش |
۱ | JTextField | txtPosition | برای نمایش موقعیت ماوس در داخل کانتینر (احتمالاً MouseMoved) |
2 | JList | lstAffichage | برای نمایش رویدادهای ماوس غیر از MouseMoved |
۳ | JButton | cmdEffacer | برای پاک کردن محتویات 2 |
وقتی این برنامه اجرا میشود، خروجی برای یک کلیک به این صورت است:

رویدادها از بالای لیست روی هم انباشته میشوند. بنابراین اسکرینشات بالا نشان میدهد که یک کلیک واحد سه رویداد را به ترتیب زیر فعال میکند:
- MousePressed وقتی دکمه فشرده میشود
- MouseReleased هنگام رها کردن دکمه
- MouseClicked، که نشان میدهد توالی دو رویداد قبلی بهعنوان یک کلیک در نظر گرفته میشود. این میتواند یک دابلکلیک باشد. با این حال، اطلاعات clickCount=1 در بالا نشان میدهد که این یک کلیک ساده است.
اکنون، اگر دکمه را فشار دهید، ماوس را حرکت دهید و دکمه را رها کنید:

در اینجا میتوانیم سه رویداد را مشاهده کنیم:
- MousePressed زمانی که دکمه برای اولین بار فشرده میشود
- MouseDragged هنگام حرکت ماوس در حالی که دکمه نگه داشته شده است
- MouseReleased زمانی که دکمه رها میشود
در دو مثال بالا، میبینیم که یک رویداد ماوس اطلاعات مختلفی از جمله مختصات (x,y) ماوس را در خود دارد، برای مثال (408,65) در خط اول بالا.
اگر به همین ترتیب ادامه دهیم، متوجه میشویم که رویداد MouseExited به محض اینکه ماوس از کانتینر خارج میشود یا روی یکی از اجزای آن قرار میگیرد، فعال میشود. در مورد دوم، کانتینر رویداد MouseExited را دریافت میکند و کامپوننت رویداد MouseEntered را دریافت میکند. وقتی ماوس از کامپوننت خارج شده و به کانتینر بازمیگردد، عکس این عمل رخ خواهد داد.
وقتی دوبار کلیک میکنید چه اتفاقی میافتد؟

رویدادها دقیقاً مانند یک کلیک ساده هستند. تنها تفاوت این است که رویداد اطلاعات clickCount=2 (به بالا مراجعه کنید) را حمل میکند که نشان میدهد در واقع یک کلیک دوگانه رخ داده است.
کد مربوطه برای این برنامه به شرح زیر است:
public class Cadre1 extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JTextField txtPosition = new JTextField();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel valeurs=new DefaultListModel();
JList lstAffichage = new JList(valeurs);
JButton cmdEffacer = new JButton();
/**چارچوب را بسازید*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
contentPane.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseMoved(MouseEvent e) {
contentPane_mouseMoved(e);
}
public void mouseDragged(MouseEvent e) {
contentPane_mouseDragged(e);
}
});
contentPane.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseEntered(MouseEvent e) {
contentPane_mouseEntered(e);
}
public void mouseExited(MouseEvent e) {
contentPane_mouseExited(e);
}
public void mousePressed(MouseEvent e) {
contentPane_mousePressed(e);
}
public void mouseClicked(MouseEvent e) {
contentPane_mouseClicked(e);
}
public void mouseReleased(MouseEvent e) {
contentPane_mouseReleased(e);
}
});
cmdEffacer.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
cmdEffacer_actionPerformed(e);
}
});
jScrollPane1.getViewport().add(lstAffichage, null);
...............
}
/**جایگزین شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
.........
}
void contentPane_mouseMoved(MouseEvent e) {
txtPosition.setText("("+e.getX()+","+e.getY()+")");
}
void contentPane_mouseDragged(MouseEvent e) {
afficher(e);
}
void contentPane_mouseEntered(MouseEvent e) {
afficher(e);
}
void afficher(MouseEvent e){
//رویداد را در لیست نمایش میدهد lstAffichage
valeurs.insertElementAt(e,0);
}
void contentPane_mouseExited(MouseEvent e) {
afficher(e);
}
void contentPane_mousePressed(MouseEvent e) {
afficher(e);
}
void contentPane_mouseClicked(MouseEvent e) {
afficher(e);
}
void contentPane_mouseReleased(MouseEvent e) {
afficher(e);
}
void cmdEffacer_actionPerformed(ActionEvent e) {
// فهرست را پاک میکند
valeurs.removeAllElements();
}
}
5.2.7. ایجاد یک پنجره با منو
حال ببینیم چگونه با استفاده از JBuilder یک پنجره با منو ایجاد کنیم. ما قصد داریم پنجره زیر را ایجاد کنیم:


یک پروژه جدید را با یک پنجره خالی ایجاد کنید. از لیست کامپوننتهای «Swing Containers»، کامپوننت JMenuBar (به شکل ۱ در زیر مراجعه کنید) را انتخاب کرده و آن را بکشید و روی پنجرهای که در حال طراحی آن هستید رها کنید.

هیچ چیزی در پنجره طراحی ظاهر نمیشود، اما کامپوننت JMenuBar در پنل ساختار پنجره شما ظاهر میشود:

روی عنصر jMenuBar1 بالا دوبار کلیک کنید تا منوی حالت طراحی باز شود:

۱ | یک آیتم منو درج کنید |
2 | وارد کردن جداکننده |
۳ | وارد کردن منوی تو در تو |
۴ | حذف یک مورد منو |
۵ | غیرفعال کردن یک مورد منو |
۶ | مورد منوی چکباکس |
7 | دکمهٔ رادیویی را جابجا کنید |
برای ایجاد اولین مورد منوی خود، عبارت «Options A» را در کادر A بالا تایپ کنید، سپس در زیر آن به ترتیب زیر: A1, A2، جداکننده، A3، A4.

سپس در کنار آن:

از ابزار ۳ استفاده کنید تا نشان دهید B3 یک زیرمنوی تو در تو است.
با طراحی منو، ساختار منطقی پنجرهٔ ما تکامل مییابد:

اگر اکنون برنامهمان را اجرا کنیم، پنجرهای خالی بدون منو خواهیم دید. باید منویی را که ایجاد کردهایم با پنجرهمان مرتبط کنیم. برای این کار، در ساختار پنجره، شیء this را انتخاب کنید:

سپس به ویژگیهای this دسترسی خواهید داشت:

یکی از این موارد JMenuBar است که برای مشخص کردن منویی که باید با پنجره مرتبط شود، استفاده میشود. در سلول سمت راست JMenuBar کلیک کنید. سپس تمام منوهایی که ایجاد کردهاید نمایش داده خواهند شد. در این مورد، ما فقط jMenuBar1 را خواهیم داشت. آن را انتخاب کنید.
برنامه را اجرا کنید (F9):

اکنون یک منو داریم، اما گزینهها در حال حاضر هیچ کاری انجام نمیدهند. گزینههای منو مانند کامپوننتها رفتار میکنند: آنها دارای خواص و رویدادها هستند. در ساختار منو، گزینه jMenuItem1 را انتخاب کنید:

سپس میتوانید به خواص و رویدادهای آن دسترسی پیدا کنید:

صفحه رویدادها را انتخاب کرده و روی سلول سمت راست رویداد actionPerformed کلیک کنید: این رویدادی است که هنگام کلیک روی یک مورد منو رخ میدهد. یک دستگیره (handler) به طور پیشفرض فراهم شده است. برای مشاهده کد آن، روی آن دوبار کلیک کنید:

ما کد ساده زیر را مینویسیم:
void jMenuItem1_actionPerformed(ActionEvent e) {
afficher("L'option A1 a été sélectionnée");
}
void afficher(String message){
// یک پیام را در یک کادر نمایش میدهد
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//نمایش
برنامه را اجرا کرده و گزینه A1 را برای نمایش پیام زیر انتخاب کنید:

کد مربوطه برای این برنامه به شرح زیر است:
.....
public class Cadre1 extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenu1 = new JMenu();
JMenuItem jMenuItem1 = new JMenuItem();
JMenuItem jMenuItem2 = new JMenuItem();
JMenuItem jMenuItem3 = new JMenuItem();
JMenuItem jMenuItem4 = new JMenuItem();
JMenu jMenu2 = new JMenu();
JMenuItem jMenuItem5 = new JMenuItem();
JMenuItem jMenuItem6 = new JMenuItem();
JMenu jMenu3 = new JMenu();
JMenuItem jMenuItem7 = new JMenuItem();
JMenuItem jMenuItem8 = new JMenuItem();
JMenuItem jMenuItem9 = new JMenuItem();
/**ساخت فریم*/
public Cadre1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
/**کامپوننت را راهاندازی کنید*/
private void jbInit() throws Exception {
//پنجره با یک منو مرتبط است
this.setJMenuBar(jMenuBar1);
jMenu1.setText("Options A");
jMenuItem1.setText("A1");
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
jMenuItem1_actionPerformed(e);
}
});
jMenuItem2.setText("A2");
jMenuItem3.setText("A3");
jMenuItem4.setText("A4");
jMenu2.setText("Options B");
jMenuItem5.setText("B1");
jMenuItem6.setText("B2");
jMenu3.setText("B3");
jMenuItem7.setText("B31");
jMenuItem8.setText("B32");
jMenuItem9.setText("B4");
jMenuBar1.add(jMenu1);
jMenuBar1.add(jMenu2);
jMenu1.add(jMenuItem1);
jMenu1.add(jMenuItem2);
jMenu1.addSeparator();
jMenu1.add(jMenuItem3);
jMenu1.add(jMenuItem4);
jMenu2.add(jMenuItem5);
jMenu2.add(jMenuItem6);
jMenu2.add(jMenu3);
jMenu2.add(jMenuItem9);
jMenu3.add(jMenuItem7);
jMenu3.add(jMenuItem8);
}
/**جایگزین شد، تا بتوانیم هنگام بستهشدن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
....
}
void jMenuItem1_actionPerformed(ActionEvent e) {
afficher("L'option A1 a été sélectionnée");
}
void afficher(String message){
// پیامی را در یک کادر نمایش میدهد
JOptionPane.showMessageDialog(this,message,"Menus",JOptionPane.INFORMATION_MESSAGE);
}//نمایش
}
5.3. جعبههای گفتگو
5.3.1. جعبههای پیام
ما قبلاً از کلاس JOptionPane برای نمایش پیامها استفاده کردهایم. برای مثال، کد زیر:
import javax.swing.*;
public class dialog1 {
public static void main(String arg[]){
JOptionPane.showMessageDialog(null,"Un message","Titre de la boîte",JOptionPane.INFORMATION_MESSAGE);
}
}
جعبهی زیر را نمایش میدهد:

هنگامی که این پنجره بسته میشود، ناپدید میشود اما نخ اجرایی که در آن در حال اجرا بود، خاتمه نمییابد. این حالت به طور معمول رخ نمیدهد. کادرهای محاوره در یک برنامه کاربردی استفاده میشوند که در مقطعی از دستور System.exit(n) برای خاتمه دادن به تمام نخها استفاده میکند. در مثالهای بعدی که همه بر اساس یک مدل یکسان هستند، این نکته را مد نظر خواهیم داشت. در سیستم عامل DOS، میتوان برنامه را با استفاده از کلید Ctrl-C خاتمه داد. با JBuilder، از گزینه Run/Reset Programme (Ctrl-F2) استفاده خواهیم کرد. علاوه بر این، آرگومان اول showMessageDialog در اینجا null است. به طور کلی، اینطور نیست. در عوض، این this است، که در آن this به پنجره اصلی برنامه اشاره دارد.
5.3.2. ظاهر و رفتار
ظاهر کادر بالا ممکن است متفاوت باشد. میتوان این ظاهر را از طریق کلاس javax.swing.UIManager پیکربندی کرد. وقتی کد تولیدشده توسط JBuilder را برای پنجره اولمان بررسی کردیم، به بیانیهای برخوردیم که روی آن تأمل نکردیم:
متد setLookAndFeel از کلاس UIManager (UI = رابط کاربری) به شما امکان میدهد ظاهر رابطهای کاربری گرافیکی را تنظیم کنید. کلاس UIManager دارای متدی برای تعیین «ظاهرهای» ممکن برای رابطها است:
static UIManager.LookAndFeelInfo[] | getInstalledLookAndFeels() |
این متد آرایهای از عناصر از نوع LookAndFeelInfo را برمیگرداند. این کلاس یک متد دارد:
رشته | getClassName() |
که نام کلاسی را که یک ظاهر و حس معین را «پیادهسازی» میکند، بازمیگرداند. بیایید برنامه زیر را امتحان کنیم:
import javax.swing.*;
public class LookAndFeels {
//نماهای ظاهری موجود را نمایش میدهد
public static void main(String[] args) {
//فهرست نماها و حسوحالات نصبشده را نمایش میدهد
UIManager.LookAndFeelInfo[] lf=UIManager.getInstalledLookAndFeels();
//نمایش
for(int i=0;i<lf.length;i++){
System.out.println(lf[i].getClassName());
}//برای
}//اصلی
}//مرتبسازی
این نتایج زیر را تولید میکند:
javax.swing.plaf.metal.MetalLookAndFeel
com.sun.java.swing.plaf.motif.MotifLookAndFeel
com.sun.java.swing.plaf.windows.WindowsLookAndFeel
بنابراین به نظر میرسد سه «سبک» «متفاوت» وجود دارد. بیایید به برنامه نمایش پیام خود بازگردیم و سبکهای مختلف ممکن را امتحان کنیم:
import javax.swing.*;
public class LookAndFeel2 {
//نماهای ظاهری موجود را نمایش میدهد
public static void main(String[] args) {
// فهرست ظاهرها و حسهای نصبشده
UIManager.LookAndFeelInfo[] lf=UIManager.getInstalledLookAndFeels();
//نمایش
for(int i=0;i<lf.length;i++){
// مدیر ظاهر
try{
UIManager.setLookAndFeel(lf[i].getClassName());
}catch(Exception ex){
System.err.println(ex.getMessage());
}//catch
// پیام
JOptionPane.showMessageDialog(null,"Un message",lf[i].getClassName(),JOptionPane.INFORMATION_MESSAGE);
}//برای
}//اصلی
}//کلاس
اجرای کد خروجی زیر را تولید میکند:
![]() | ![]() | ![]() |
مطابق با، از راست به چپ، تمهای «فلز»، «الگو» و «پنجرهها».
5.3.3. جعبههای تأیید
کلاس JOptionPane دارای متدی به نام showConfirmDialog برای نمایش جعبههای تأیید با دکمههای Oui است، Non و Annuler. چندین متد showConfirmDialog بازنویسی شدهاند. ما یکی از آنها را بررسی خواهیم کرد:
ثابت int | showConfirmDialog(Component parentComponent, Object message, String title, int optionType) |
parentComponent | کامپوننت والدِ کادرِ گفتگو. اغلب پنجره یا مقدار null |
message | پیامی که باید نمایش داده شود |
title | عنوان کادر گفتگو |
optionType | JOptionPane.YES_NO_OPTION: دکمههای بله، نه JOptionPane.YES_NO_CANCEL_OPTION: دکمههای «بله»، «خیر»، «لغو» |
نتیجهای که توسط متد بازگردانده میشود:
JOptionPane.YES_OPTION | کاربر روی «بله» کلیک کرد |
JOptionPane.NO_OPTION | کاربر روی «خیر» کلیک کرد |
JOptionPane.CANCEL_OPTION | کاربر روی «لغو» کلیک کرد |
JOptionPane.CLOSED_OPTION | کاربر پنجره را بست |
در اینجا یک مثال آورده شده است:
import javax.swing.*;
public class confirm1 {
public static void main(String[] args) {
// نمایش جعبههای تأیید
int réponse;
affiche(JOptionPane.showConfirmDialog(null,"Voulez-vous continuer ?","Confirmation",JOptionPane.YES_NO_OPTION));
affiche(JOptionPane.showConfirmDialog(null,"Voulez-vous continuer ?","Confirmation",JOptionPane.YES_NO_CANCEL_OPTION));
}//اصلی
private static void affiche(int réponse){
// نوع پاسخی را که دریافت شده است نشان میدهد
switch(réponse){
case JOptionPane.YES_OPTION :
System.out.println("Oui");
break;
case JOptionPane.NO_OPTION :
System.out.println("Non");
break;
case JOptionPane.CANCEL_OPTION :
System.out.println("Annuler");
break;
case JOptionPane.CLOSED_OPTION :
System.out.println("Fermeture");
break;
}//سوئیچ
}//نمایش
}//مرتبسازی
![]() | ![]() |
در کنسول، پیامهای Non و Annuler نمایش داده میشوند.
5.3.4. میدان ورودی
کلاس JOptionPane همچنین امکان وارد کردن دادهها را با استفاده از متد showInputDialog فراهم میکند. در اینجا نیز چندین متد اِبربارگذاریشده وجود دارد. ما یکی از آنها را ارائه میدهیم:
ثابت رشته | showInputDialog(Component parentComponent, Object message, String title, int messageType) |
آرگومانها همانهایی هستند که قبلاً چندین بار با آنها مواجه شدهایم. این متد رشتهای را که کاربر تایپ کرده است بازمیگرداند. در اینجا یک مثال آمده است:
import javax.swing.*;
public class input1 {
public static void main(String[] args) {
// ورودی
System.out.println("Chaîne saisie ["+
JOptionPane.showInputDialog(null,"Quel est votre nom","Saisie du nom",JOptionPane.QUESTION_MESSAGE )
+ "]");
}//دست
}//کلاس
نمایش کادر ورودی:

نمایش کنسول:
5.4. جعبههای انتخاب
اکنون به تعدادی از کادرهای انتخاب از پیش تعریفشده در جاوا 2 میپردازیم:
JFileChooser | یک کادر انتخاب برای انتخاب یک فایل از درخت فایلها |
JColorChooser | یک کادر انتخاب برای انتخاب رنگ |
5.4.1. JFileChooser جعبهی انتخاب
ما قصد داریم اپلیکیشن زیر را بسازیم:

کنترلها به شرح زیر هستند:
خیر. | نوع | name | نقش |
0 | JScrollPane | jScrollPane1 | ظرف قابل پیمایش برای کادر متن ۱ |
1 | خود JTextArea درون JScrollPane | txtTexte | متن تایپشده توسط کاربر یا بارگذاریشده از یک فایل |
2 | JButton | btnSauvegarder | امکان ذخیره متن از ۱ در یک فایل متنی را فراهم میکند |
3 | JButton | btnCharger | امکان بارگذاری محتویات یک فایل متنی را به 1 میدهد |
۴ | JButton | btnEffacer | محتویات 1 را پاک میکند |
یک کنترل غیرگرافیکی استفاده میشود: jFileChooser1. این از پالت محفظههای Swing JBuilder گرفته شده است:

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

اکنون برای ارائه یک نمای کلی، کد برنامه مربوطه را ارائه میدهیم:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
public class dialogues extends JFrame {
//اجزای فریم
JPanel contentPane;
JButton btnSauvegarder = new JButton();
JButton btnCharger = new JButton();
JButton btnEffacer = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
JTextArea txtTexte = new JTextArea();
JFileChooser jFileChooser1 = new JFileChooser();
//فیلترهای فایل
javax.swing.filechooser.FileFilter filtreTxt = null;
//ساخت فریم
public dialogues() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
// سایر راهاندازیها
moreInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
// moreInit
private void moreInit(){
// ابتکاریات هنگام ساخت پنجره
// فیلتر *.txt
filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
//آیا 'f' پذیرفته میشود؟
return f.getName().toLowerCase().endsWith(".txt");
}//قبول
public String getDescription(){
// توضیحات فیلتر
return "Fichiers Texte (*.txt)";
}//getDescription
};
// ما فیلتر را اضافه میکنیم
jFileChooser1.addChoosableFileFilter(filtreTxt);
// ما همچنین یک فیلتر برای همه فایلها میخواهیم
jFileChooser1.setAcceptAllFileFilterUsed(true);
// مخزن منبع برای پوشه FileChooser را روی دایرکتوری جاری تنظیم کنید
jFileChooser1.setCurrentDirectory(new File("."));
}
//کامپوننت را راهاندازی کنید
private void jbInit() throws Exception {
.......................
}
//جایگزین شد، بنابراین میتوانیم هنگام بستهشدن پنجره خروج کنیم
protected void processWindowEvent(WindowEvent e) {
......................
}
}
void btnCharger_actionPerformed(ActionEvent e) {
//انتخاب یک فایل با استفاده از یک شیء JFileChooser
// فیلتر اولیه را تنظیم کنید
jFileChooser1.setFileFilter(filtreTxt);
// نمایش جعبهی انتخاب
int returnVal = jFileChooser1.showOpenDialog(this);
// آیا کاربر چیزی را انتخاب کرده است؟
if(returnVal == JFileChooser.APPROVE_OPTION) {
// قرار دادن فایل در فیلد متن
lireFichier(jFileChooser1.getSelectedFile());
}//اگر
}//btnCharger_actionPerformed
// lireFichier
private void lireFichier(File fichier){
//محتویات فایل متنی 'fichier' را در فیلد متن نمایش میدهد
// میدان متن را پاک میکند
txtTexte.setText("");
// دادههای برخی
BufferedReader IN=null;
String ligne=null;
try{
// فایل را در حالت فقط خواندنی باز میکند
IN=new BufferedReader(new FileReader(fichier));
// فایل را خط به خط میخواند
while((ligne=IN.readLine())!=null){
txtTexte.append(ligne+"\n");
}//در حالی که
// بستن فایل
IN.close();
}catch(Exception ex){
// یک خطا رخ داده است
txtTexte.setText(""+ex);
}//catch
}
//پاک کردن
void btnEffacer_actionPerformed(ActionEvent e) {
// پاک کردن کادر متن
txtTexte.setText("");
}
// ذخیره
void btnSauvegarder_actionPerformed(ActionEvent e) {
// محتویات کادر متن را در یک فایل ذخیره میکند
// تنظیم فیلتر اولیه
jFileChooser1.setFileFilter(filtreTxt);
// نمایش پنجرهٔ انتخاب ذخیره
int returnVal = jFileChooser1.showSaveDialog(this);
// آیا کاربر چیزی را انتخاب کرده است؟
if(returnVal == JFileChooser.APPROVE_OPTION) {
// نوشتن محتویات کادر متن در یک فایل
écrireFichier(jFileChooser1.getSelectedFile());
}//اگر
}
// lireFichier
private void écrireFichier(File fichier){
// محتویات کادر متن را به یک فایل مینویسد
// دادههایی
PrintWriter PRN=null;
try{
// فایل را برای نوشتن باز میکند
PRN=new PrintWriter(new FileWriter(fichier));
//محتویات کادر متن را مینویسد
PRN.print(txtTexte.getText());
// فایل را میبندد
PRN.close();
}catch(Exception ex){
//یک خطا رخ داده است
txtTexte.setText(""+ex);
}//catch
}
ما در مورد کد متدهای btnEffacer_Click، lireFichier و écrireFichier توضیحی ارائه نمیدهیم، زیرا آنها چیزی را معرفی نمیکنند که قبلاً پوشش داده نشده باشد. ما بر کلاس JFileChooser و نحوه استفاده از آن تمرکز خواهیم کرد. این کلاس پیچیده و نسبتاً درهمتنیده است. در اینجا، ما فقط از متدهای زیر استفاده میکنیم:
addChoosableFilter(FileFilter) | انواع فایلهای در دسترس برای انتخاب را تعیین میکند |
setAcceptAllFileFilterUsed(boolean) | مشخص میکند که آیا گزینه «تمام فایلها» باید برای انتخاب ارائه شود یا خیر |
File getSelectedFile() | فایل (File) انتخابشده توسط کاربر |
int showSaveDialog() | متدی که کادر محاورهای ذخیره را نمایش میدهد. مقداری از نوع int را برمیگرداند. مقدار jFileChooser.APPROVE_OPTION نشان میدهد که کاربر یک انتخاب معتبر انجام داده است. در غیر این صورت، یا انتخاب را لغو کرده یا خطایی رخ داده است. |
setCurrentDirectory | برای تنظیم دایرکتوری اولیه که کاربر از آن شروع به کاوش در سیستم فایل میکند |
setFileFilter(FileFilter) | برای تنظیم فیلتر فعال |
متد showSaveDialog یک کادر انتخاب مشابه شکل زیر را نمایش میدهد:

1 | لیست کشویی ایجادشده با استفاده از متد addChoosableFilter. این لیست شامل فیلترهای انتخابی است که توسط کلاس FileFilter نمایش داده میشوند. بر عهده توسعهدهنده است که این فیلترها را تعریف کرده و به لیست 1 اضافه کند. |
۲ | پوشهٔ جاری، که توسط متد setCurrentDirectory در صورت استفاده از این متد تنظیم میشود؛ در غیر این صورت، پوشهٔ جاری، پوشهٔ «My Documents» در ویندوز یا پوشهٔ خانگی در یونیکس خواهد بود. |
۳ | نام فایلی که توسط کاربر انتخاب یا مستقیماً وارد شده است. از طریق متد getSelectedFile() در دسترس خواهد بود. |
4 | دکمههای ذخیره/لغو. اگر دکمه Enregistrer استفاده شود، متد showSaveDialog نتیجه را به jFileChooser.APPROVE_OPTION بازمیگرداند |
فیلترهای فایل برای لیست کشویی 1 چگونه ساخته میشوند؟ فیلترها با استفاده از متد زیر به لیست 1 اضافه میشوند:
addChoosableFilter(FileFilter) | انواع فایلهای در دسترس برای انتخاب را تعیین میکند |
از کلاس JFileChooser. ما همچنان باید کلاس FileFilter را درک کنیم. این در واقع کلاس javax.swing.filechooser.FileFilter است، که یک کلاس انتزاعی است، c.a.d – کلاسی که نمیتوان آن را نمونهسازی کرد، بلکه فقط میتوان از آن ارث برد. این به شرح زیر تعریف شده است:
FileFilter() | سازنده |
boolean accept(File) | نشان میدهد که آیا فایل f به فیلتر تعلق دارد یا خیر |
String getDescription() | رشتهٔ توصیف فیلتر |
بیایید یک مثال بزنیم. ما میخواهیم لیست کشویی 1 فیلتری برای انتخاب فایلهای *.txt با توضیح «فایلهای متنی (*.txt)» ارائه دهد.
- ما باید یک کلاس مشتقشده از کلاس FileFilter ایجاد کنیم
- از متد بولین `accept(File f)` استفاده کنید تا در صورتی که نام فایل `f` با .txt پایان یابد، مقدار true را بازگردانید.
- از متد String با نام getDescription() برای بازگرداندن توضیح «فایلهای متنی (*.txt)» استفاده کنید
این فیلتر میتواند در برنامه ما به صورت زیر تعریف شود:
javax.swing.filechooser.FileFilter filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
//آیا باید f پذیرفته شود؟
return f.getName().toLowerCase().endsWith(".txt");
}//قبول
public String getDescription(){
// توضیحات فیلتر
return "Fichiers Texte (*.txt)";
}//getDescription
};
این فیلتر با استفاده از عبارت زیر به لیست فیلترهای شیء jFileChooser1 اضافه میشود:
تمام این موارد، به همراه چند مقداردهی اولیه دیگر، در متد moreInit انجام میشود که هنگام ایجاد پنجره اجرا میگردد (به برنامه کامل بالا مراجعه کنید). کد دکمه Sauvegarder به شرح زیر است:
void btnSauvegarder_actionPerformed(ActionEvent e) {
// محتویات کادر متن را در یک فایل ذخیره میکند
// تنظیم فیلتر اولیه
jFileChooser1.setFileFilter(filtreTxt);
// نمایش پنجرهٔ تأیید ذخیره
int returnVal = jFileChooser1.showSaveDialog(this);
//آیا کاربر چیزی را انتخاب کرده است؟
if(returnVal == JFileChooser.APPROVE_OPTION) {
//محتویات کادر متن را در یک فایل مینویسد
écrireFichier(jFileChooser1.getSelectedFile());
}//اگر
}
ترتیب عملیات به شرح زیر است:
- فیلتر فعال روی *.txt تنظیم شده است تا کاربر بتواند عمدتاً این نوع فایل را جستجو کند. فیلتر «تمام فایلها» نیز موجود است. این فیلتر در رویه moreInit اضافه شده است. بنابراین دو فیلتر وجود دارد.
- کادر محاورهای ذخیره نمایش داده میشود. در این نقطه، کنترل به کاربر واگذار میشود تا با استفاده از کادر محاورهای، فایلی را از سیستم فایل انتخاب کند.
- هنگامی که کاربر از کادر انتخاب خارج میشود، مقدار بازگشتی بررسی میشود تا مشخص شود که آیا متن باید ذخیره شود یا خیر. در صورت مثبت بودن پاسخ، باید در فایلی که از طریق متد getSelectedFile به دست آمده، ذخیره شود.
کد مربوط به دکمه «بارگذاری» بسیار شبیه کد دکمه «ذخیره» است.
void btnCharger_actionPerformed(ActionEvent e) {
// یک فایل را با استفاده از یک شیء JFileChooser انتخاب کنید
// فیلتر اولیه را تنظیم کنید
jFileChooser1.setFileFilter(filtreTxt);
// جعبهی انتخاب را نمایش دهید
int returnVal = jFileChooser1.showOpenDialog(this);
//آیا کاربر چیزی را انتخاب کرده است؟
if(returnVal == JFileChooser.APPROVE_OPTION) {
// قرار دادن فایل در فیلد متن
lireFichier(jFileChooser1.getSelectedFile());
}//اگر
}//btnCharger_actionPerformed
دو تفاوت وجود دارد:
- برای نمایش کادر محاورهای انتخاب فایل، روش showOpenDialog به جای روش showSaveDialog استفاده میشود. کادر محاورهای انتخاب نمایشدادهشده مشابه کادری است که توسط روش showSaveDialog نمایش داده میشود.
- اگر کاربر با موفقیت یک فایل را انتخاب کند، متد lireFichier فراخوانی میشود، نه متد écrireFichier.
5.4.1.1. جعبههای انتخاب JColorChooser و JFontChooser
ما با مثال قبلی ادامه میدهیم و دو دکمه جدید اضافه میکنیم:

خیر. | نوع | name | نقش |
۶ | JButton | btnCouleur | برای تنظیم رنگ متن برای TextBox |
7 | JButton | btnPolice | برای تنظیم قلم برای TextBox |
کامپوننت JColorChooser که یک انتخابگر رنگ را نمایش میدهد، را میتوان در لیست کامپوننتهای Swing برای JBuilder یافت:

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

کلاس JColorChooser بسیار ساده است. ما با استفاده از متد int showDialog: انتخابگر رنگ را نمایش میدهیم:
ثابت Color | showDialog(Component component, String title, Color initialColor) |
Component component | کامپوننت والد انتخابگر رنگ، معمولاً یک پنجره JFrame |
رشته title | عنوان نمایشدادهشده در نوار عنوان کادر انتخاب |
رنگ intialColor | رنگ انتخابشده در ابتدا در انتخابگر |
اگر کاربر رنگی را انتخاب کند، متد یک رنگ را برمیگرداند؛ در غیر این صورت، مقدار null را برمیگرداند. کد مربوط به دکمه Couleur به شرح زیر است:
void btnCouleur_actionPerformed(ActionEvent e) {
// با استفاده از مؤلفه QZXW2HTMLCSkNvbG9yQ2hhcmdlcl9hY3Rpb25QZXJmb3JtZWQX رنگ متن را انتخاب کنید
Color couleur;
if((couleur=jColorChooser1.showDialog(this,"Choix d'une couleur",Color.BLACK))!=null){
//تنظیم رنگ متن در کادر متن
txtTexte.setForeground(couleur);
}//if
}
کلاس Color در java.awt.Color تعریف شده است. ثابتهای مختلفی در آنجا تعریف شدهاند، از جمله Color.BLACK برای رنگ سیاه. جعبهی انتخاب نمایشدادهشده به شرح زیر است

جالب اینجاست که کتابخانهٔ Swing کلاسی برای انتخاب قلم ارائه نمیدهد. خوشبختانه منابع جاوا بهصورت آنلاین در دسترس هستند. با جستجوی عبارت «JFontChooser» – که به نظر میرسد نام احتمالی چنین کلاسی باشد – چندین نتیجه قابل یافتن است. مثال زیر نشان میدهد چگونه JBuilder را برای استفاده از بستههایی که در پیکربندی اولیه آن گنجانده نشدهاند، پیکربندی کنیم.
پکیج بازیابیشده swingextras.jar نام دارد و در پوشه <jdk>\jre\lib\perso قرار گرفته است، که در آن <jdk> به مسیر نصب JDK مورد استفاده توسط JBuilder اشاره دارد. میتوانست در هر جای دیگری قرار داده شود.
![]() | ![]() |
بیایید محتویات بسته SwingExtras.jar را بررسی کنیم:

این شامل کد منبع جاوا برای کامپوننتهای موجود در بسته است. همچنین خود کلاسها را نیز در بر میگیرد:

از این آرشیو، شایان ذکر است که کلاس JFontChooser در واقع با نام com.lamatek.swingextras.JFontChooser نامگذاری شده است. اگر مایل نیستید نام کامل را بنویسید، باید در ابتدای برنامه موارد زیر را بنویسید:
کامپایلر و ماشین مجازی جاوا این بسته جدید را چگونه پیدا خواهند کرد؟ در مورد استفاده مستقیم از JDK، این موضوع قبلاً توضیح داده شده است و خواننده میتواند جزئیات را در بخش مربوط به بستههای جاوا بیابد. در اینجا، روش استفاده با JBuilder را به تفصیل توضیح میدهیم. پکیجها در منوی Options/Configure JDK پیکربندی میشوند:

1 | دکمه Modifier (۱) به شما امکان میدهد به JBuilder مشخص کنید که کدام JDK را استفاده کند. در این مثال، JBuilder نسخه ۱.۳.۱ از JDK را همراه خود آورده بود. وقتی JDK نسخه 1.4 منتشر شد، بهطور جداگانهای از JBuilder نصب شد و از دکمه Modifier برای دستور دادن به JBuilder استفاده شداکنون با مشخص کردن پوشه نصب JDK 1.4 از آن استفاده کنید |
۲ | پوشهٔ پایهٔ JDK که در حال حاضر توسط JBuilder استفاده میشود |
۳ | فهرست آرشیوهای جاوا (.jar) مورد استفاده توسط JBuilder. آرشیوهای بیشتری را میتوان با استفاده از دکمه Ajouter (۴) اضافه کرد. |
۴ | دکمه Ajouter (۴) به شما امکان میدهد پکیجهای جدیدی را اضافه کنید که JBuilder برای کامپایل و اجرای برنامهها از آنها استفاده خواهد کرد. در اینجا برای افزودن پکیج SwingExtras.jar (۵) استفاده شده است. |
JBuilder اکنون به درستی برای استفاده از کلاس JFontChooser پیکربندی شده است. با این حال، برای استفاده صحیح از آن، به دسترسی به تعریف این کلاس نیاز داریم. آرشیو swingextras.jar حاوی فایلهای HTML است که میتوانیم برای این منظور استخراج کنیم. این کار غیرضروری است. مستندات جاوا که در فایلهای .jar گنجانده شده است، مستقیماً از JBuilder قابل دسترسی است. برای این کار، باید زبانه Documentation (۶) را در بالا پیکربندی کنید. پنجره جدید زیر ظاهر میشود:

دکمه Ajouter به شما امکان میدهد مشخص کنید که فایل SwingExtras.jar باید برای مستندات اسکن شود. پس از تأیید این موضوع، خواهید دید که واقعاً به مستندات SwingExtras.jar دسترسی دارید. این امر مزایای متعددی را ارائه میدهد:
- اگر شروع به تایپ عبارت import کنیم
مشاهده خواهیم کرد که JBuilder راهنمایی ارائه میدهد:

پکیج com.lamatek یافت شد.
- اکنون، اگر به برنامه زیر نگاه کنیم:
اگر F1 را با کلیدواژه JFontChooser اجرا کنید، راهنمای این کلاس را دریافت میکنید:

ما میتوانیم در نوار وضعیت ۱ ببینیم که در واقع یک فایل HTML از بسته swingextras.jar در حال استفاده است. مثال نشان داده شده در بالا به اندازه کافی واضح است تا بتوانیم کد دکمه Police را در برنامه خود بنویسیم:
void btnPolice_actionPerformed(ActionEvent e) {
// انتخاب فونت متن با استفاده از کامپوننت JFontChooser
jFontChooser1 = new JFontChooser(new Font("Arial", Font.BOLD, 12));
if (jFontChooser1.showDialog(this, "Choix d'une police") == JFontChooser.ACCEPT_OPTION) {
//تغییر فونت کادر متن
txtTexte.setFont(jFontChooser1.getSelectedFont());
}//if
}
جعبه انتخاب نمایشدادهشده توسط روش showDialog فوق به شرح زیر است:

5.5. برنامه گرافیکی IMPOTS
ما به برنامه IMPOTS بازمیگردیم که قبلاً دو بار بررسی شده است. اکنون یک رابط گرافیکی به آن اضافه میکنیم:

کنترلها به شرح زیر هستند
خیر. | نوع | نام | نقش |
1 | JRadioButton | rdOui | در صورت متأهل بودن تیک خورده |
2 | JRadioButton | rdNon | تیک خورده در صورت متأهل نبودن |
3 | JSpinner | spinEnfants | تعداد فرزندان مؤدی حداقل=0، حداکثر=20، گام=1 |
۴ | JTextField | txtSalaire | حقوق سالانه مالیاتدهنده به F |
۵ | JLabel | lblImpots | مبلغ مالیات پرداختنی |
۶ | JTextField | txtStatus | میدان پیام وضعیت – قابل ویرایش نیست |
منو به شرح زیر است:
گزینهٔ اصلی | گزینهٔ ثانویه | نام | نقش |
مالیاتها | |||
ابتداییسازی | mnuInitialiser | بارگذاری دادههای مورد نیاز برای محاسبه از یک فایل متنی | |
محاسبه | mnuCalculer | پس از موجود و صحیح بودن تمام دادههای لازم، مالیات قابل پرداخت را محاسبه میکند | |
پاک کردن | mnuEffacer | فرم را به وضعیت اولیهٔ خود بازمیگرداند | |
خروج | mnuQuitter | برنامه را میبندد |
قوانین عملیاتی
- منوی Calculer تا زمانی که فیلد حقوق پر نشود، مخفی میماند
- اگر هنگام اجرای محاسبه، مشخص شود که حقوق نادرست است، خطایی گزارش میشود:

برنامه در زیر نشان داده شده است. این برنامه از کلاس impots که در فصل مربوط به کلاسها ایجاد شده است، استفاده میکند. برخی از کدهای تولید شده بهطور خودکار توسط JBuilder در اینجا بازتولید نشدهاند.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.io.*;
import java.util.*;
import javax.swing.event.*;
public class frmImpots extends JFrame {
// اجزای پنجره
JPanel contentPane;
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenu1 = new JMenu();
JMenuItem mnuInitialiser = new JMenuItem();
JMenuItem mnuCalculer = new JMenuItem();
JMenuItem mnuEffacer = new JMenuItem();
JMenuItem mnuQuitter = new JMenuItem();
JLabel jLabel1 = new JLabel();
JFileChooser jFileChooser1 = new JFileChooser();
JTextField txtStatus = new JTextField();
JRadioButton rdOui = new JRadioButton();
JRadioButton rdNon = new JRadioButton();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSalaire = new JTextField();
JLabel jLabel4 = new JLabel();
JLabel jLabel5 = new JLabel();
JLabel lblImpots = new JLabel();
JLabel jLabel7 = new JLabel();
ButtonGroup buttonGroup1 = new ButtonGroup();
JSpinner spinEnfants=null;
FileFilter filtreTxt=null;
// ویژگیهای کلاس
double[] limites=null;
double[] coeffr=null;
double[] coeffn=null;
impots objImpots=null;
//چارچوب را بسازید
public frmImpots() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
//سایر راهاندازیها
moreInit();
}
// ابتکاری فرم
private void moreInit(){
// منوی «حساب کردن» غیرفعال است
mnuCalculer.setEnabled(false);
// میدانهای ورودی غیرفعال
txtSalaire.setEditable(false);
txtSalaire.setBackground(Color.WHITE);
// میدان وضعیت
txtStatus.setBackground(Color.WHITE);
//چرخوفلک فرزندان – بین ۰ و ۲۰ فرزند
spinEnfants=new JSpinner(new SpinnerNumberModel(0,0,20,1));
spinEnfants.setBounds(new Rectangle(137,60,40,27));
contentPane.add(spinEnfants);
// فیلتر *.txt برای لیست کشویی
filtreTxt = new javax.swing.filechooser.FileFilter(){
public boolean accept(File f){
//آیا 'f' پذیرفته میشود؟
return f.getName().toLowerCase().endsWith(".txt");
}//قبول
public String getDescription(){
// توضیحات فیلتر
return "Fichiers Texte (*.txt)";
}//getDescription
};
// ما فیلتر *.txt را اضافه میکنیم
jFileChooser1.addChoosableFileFilter(filtreTxt);
// ما همچنین یک فیلتر برای همه فایلها میخواهیم
jFileChooser1.setAcceptAllFileFilterUsed(true);
// مخزن منبع را برای پوشه FileChooser تنظیم کنید
jFileChooser1.setCurrentDirectory(new File("."));
}//moreInit
//کامپوننت را راهاندازی کنید
private void jbInit() throws Exception {
................
}
//جایگزین شد، بنابراین میتوانیم هنگام بستهشدن پنجره خروج کنیم
protected void processWindowEvent(WindowEvent e) {
.....................
}
void mnuQuitter_actionPerformed(ActionEvent e) {
//خروج از برنامه
System.exit(0);
}
void mnuInitialiser_actionPerformed(ActionEvent e) {
// بارگذاری فایل داده
// که با استفاده از کادر انتخاب JFileChooser1 انتخاب شده است
jFileChooser1.setFileFilter(filtreTxt);
if (jFileChooser1.showOpenDialog(this)!=JFileChooser.APPROVE_OPTION)
return;
// فایل انتخابی پردازش میشود
try{
// خواندن دادهها
lireFichier(jFileChooser1.getSelectedFile());
// ایجاد شیء 'impots'
objImpots=new impots(limites,coeffr,coeffn);
//تأیید
txtStatus.setText("Données chargées");
// حقوق قابل اصلاح است
txtSalaire.setEditable(true);
// دیگر امکان تغییر وجود ندارد
mnuInitialiser.setEnabled(false);
}catch(Exception ex){
// مشکل
txtStatus.setText("Erreur : " + ex.getMessage());
//پایان
return;
}//catch
}
private void lireFichier(File fichier) throws Exception {
// جدولهای داده
ArrayList aLimites=new ArrayList();
ArrayList aCoeffR=new ArrayList();
ArrayList aCoeffN=new ArrayList();
String[] champs=null;
// باز کردن فایل برای خواندن
BufferedReader IN=new BufferedReader(new FileReader(fichier));
// فایل خط به خط خوانده میشود
//آنها به شکل limit coeffr coeffn هستند
String ligne=null;
int numLigne=0; // شماره خط جاری
while((ligne=IN.readLine())!=null){
//یک خط دیگر
numLigne++;
// خط به فیلدها تقسیم میشود
champs=ligne.split("\\s+");
// ۳ فیلد؟
if(champs.length!=3)
throw new Exception("ligne " + numLigne + "erronée dans fichier des données");
//سه فیلد را بازیابی کنید
aLimites.add(champs[0]);
aCoeffR.add(champs[1]);
aCoeffN.add(champs[2]);
}//در حالی که
// بستن فایل
IN.close();
//دادهها را به آرایههای محدود منتقل میکند
int n=aLimites.size();
limites=new double[n];
coeffr=new double[n];
coeffn=new double[n];
for(int i=0;i<n;i++){
limites[i]=Double.parseDouble((String)aLimites.get(i));
coeffr[i]=Double.parseDouble((String)aCoeffR.get(i));
coeffn[i]=Double.parseDouble((String)aCoeffN.get(i));
}//برای
}
void mnuCalculer_actionPerformed(ActionEvent e) {
//محاسبه مالیات
//بررسی حقوق
int salaire=0;
try{
salaire=Integer.parseInt(txtSalaire.getText().trim());
if(salaire<0) throw new Exception();
}catch (Exception ex){
// پیام خطا
txtStatus.setText("Salaire incorrect. Recommencez");
//تمرکز روی فیلد اشتباه
txtSalaire.requestFocus();
//بازگشت به رابط کاربری
return;
}
// تعداد فرزندان
Integer InbEnfants=(Integer)spinEnfants.getValue();
// محاسبه مالیات
lblImpots.setText(""+objImpots.calculer(rdOui.isSelected(),InbEnfants.intValue(),salaire));
// پاک کردن پیام وضعیت
txtStatus.setText("");
}
void txtSalaire_caretUpdate(CaretEvent e) {
// حقوق تغییر کرده است – منوی «حساب کردن» را بهروزرسانی کنید
mnuCalculer.setEnabled(! txtSalaire.getText().trim().equals(""));
}
void mnuEffacer_actionPerformed(ActionEvent e) {
// پاک کردن فرم
rdNon.setSelected(true);
spinEnfants.getModel().setValue(new Integer(0));
txtSalaire.setText("");
mnuCalculer.setEnabled(false);
lblImpots.setText("");
}
}
در اینجا از کامپوننتی استفاده کردهایم که تنها از نسخه ۱.۴ به بعد در JDK موجود است، یعنی JSpinner. این یک افزاینده است که در این مورد به کاربر اجازه میدهد تعداد فرزندان را تنظیم کند. این کامپوننت Swing در نوار کامپوننتهای Swing نسخه JBuilder 6 که برای آزمایش استفاده شد، موجود نبود. این امر مانع از استفاده از آن نمیشود، هرچند کار کمی پیچیدهتر از کامپوننتهای موجود در نوار کامپوننتها است. در واقع، کامپوننت JSpinner را نمیتوان در زمان طراحی روی فرم قرار داد. این کار باید در زمان اجرا انجام شود. بیایید نگاهی به کدی بیندازیم که این کار را انجام میدهد:
// چرخفلک تعداد فرزندان – بین ۰ تا ۲۰ فرزند وارد کنید
spinEnfants=new JSpinner(new SpinnerNumberModel(0,0,20,1));
spinEnfants.setBounds(new Rectangle(137,60,40,27));
contentPane.add(spinEnfants);
خط اول کامپوننت JSpinner را ایجاد میکند. این کامپوننت میتواند برای اهداف مختلف استفاده شود، نه فقط بهعنوان یک شمارشگر عدد صحیح همانطور که در اینجا نشان داده شده است. آرگومان سازنده JSpinner یک قالب افزایشدهنده عدد است که چهار پارامتر (value، min، max، increment) را میپذیرد. این کامپوننت به شکل زیر است:
![]()
valeur | مقدار اولیه نمایش داده شده در کامپوننت |
min | حداقل مقداری که میتواند در کامپوننت نمایش داده شود |
max | حداکثر مقداری که میتواند در مؤلفه نمایش داده شود |
incrément | مقدار افزایشی برای مقدار نمایشدادهشده هنگام استفاده از فلشهای بالا/پایین کامپوننت |
مقدار کامپوننت از طریق متد آن getValue به دست میآید که نوع Object را برمیگرداند. بنابراین، برای به دست آوردن عدد صحیح مورد نیاز، به چند تبدیل نوع نیاز است:
//تعداد فرزندان
Integer InbEnfants=(Integer)spinEnfants.getValue();
//محاسبه مالیات
lblImpots.setText(""+objImpots.calculer(rdOui.isSelected(),
InbEnfants.intValue(),salaire));
پس از تعریف کامپوننت JSpinner، در پنجره قرار داده میشود:
ابتدا، کاربر باید از گزینه منوی Initialiser استفاده کند که با استفاده از سازنده، یک شیء impots ایجاد میکند
از کلاس impots. توجه داشته باشید که این کلاس بهعنوان یک مثال در فصل مربوط به کلاسها تعریف شده است. در صورت نیاز به آن فصل مراجعه کنید. سه آرایه مورد نیاز سازنده با استفاده از محتویات یک فایل متنی با فرمت زیر پر میشوند:
12620.0 | 0 | 0 |
13190 | 0.05 | ۶۳۱ |
۱۵٬۶۴۰ | 0.1 | ۱٬۲۹۰٫۵ |
۲۴٬۷۴۰ | 0.15 | ۲٬۰۷۲٫۵ |
۳۱٬۸۱۰ | 0.2 | ۳٬۳۰۹٫۵ |
۳۹٬۹۷۰ | 0.25 | ۴٬۹۰۰ |
۴۸٬۳۶۰ | 0.3 | ۶۸۹۸.۵ |
۵۵٬۷۹۰ | 0.35 | ۹٬۳۱۶٫۵ |
۹۲٬۹۷۰ | 0.4 | ۱۲٬۱۰۶ |
۱۲۷٬۸۶۰ | 0.45 | ۱۶٬۷۵۴٫۵ |
۱۵۱٬۲۵۰ | 0.50 | ۲۳٬۱۴۷٫۵ |
۱۷۲٬۰۴۰ | 0.55 | ۳۰٬۷۱۰ |
۱۹۵٬۰۰۰ | 0.60 | ۳۹٬۳۱۲ |
0 | 0.65 | ۴۹٬۰۶۲ |
هر خط شامل سه عدد است که با حداقل یک فاصله از هم جدا شدهاند. این فایل متنی توسط کاربر با استفاده از کامپوننت JFileChooser انتخاب میشود. پس از ایجاد شیء impots، تنها کاری که باقی میماند این است که به کاربر اجازه دهید سه اطلاعات مورد نیاز را وارد کند: وضعیت تأهل، تعداد فرزندان و حقوق سالانه، و سپس متد calculer از کلاس impots را فراخوانی کند. این عملیات را میتوان چندین بار تکرار کرد. با این حال، شیء از نوع impots تنها یک بار، زمانی که گزینه Initialiser استفاده میشود، ایجاد میگردد.
5.6. نوشتن اپلتها
5.6.1. مقدمه
پس از اینکه یک برنامه با رابط کاربری گرافیکی نوشتید، تبدیل آن به applet نسبتاً ساده است. این برنامه که روی ماشین A ذخیره شده، میتواند از طریق یک مرورگر وب از ماشین B از طریق اینترنت دانلود شود. بدین ترتیب، برنامهٔ اصلی در میان کاربران زیادی به اشتراک گذاشته میشود و این مزیت اصلی تبدیل یک برنامه به یک اپلت است. با این حال، هر برنامهای را نمیتوان به این روش تبدیل کرد: برای اطمینان از اینکه کاربرانی که اپلت را در مرورگر خود اجرا میکنند با مشکل مواجه نشوند، محیط اپلت محدود شده است:
- یک اپلت نمیتواند از هارد دیسک کاربر بخواند یا روی آن بنویسد
- این اپلت تنها میتواند با ماشینی که از طریق مرورگر از آن دانلود شده است، ارتباط برقرار کند.
اینها محدودیتهای قابل توجهی هستند. این بدان معناست که برای مثال، یک برنامهای که نیاز به خواندن اطلاعات از یک فایل یا پایگاه داده دارد، باید آن را از طریق یک برنامه واسط که روی سروری که از آن دانلود شده قرار دارد، درخواست کند.
ساختار کلی یک برنامه وب ساده به شرح زیر است:

- کلاینت یک سند HTML را معمولاً از طریق یک مرورگر از وبسرور درخواست میکند. این سند ممکن است حاوی یک اپلت باشد که بهعنوان یک برنامه گرافیکی مستقل در داخل سند HTML نمایشدادهشده توسط مرورگر کلاینت عمل خواهد کرد.
- این اپلت قادر به دسترسی به دادهها خواهد بود، اما فقط به دادههایی که در سرور وب قرار دارند. این اپلت به منابع روی ماشین کلاینتی که آن را اجرا میکند، و همچنین به منابع روی سایر ماشینهای شبکه به غیر از ماشینی که از آن دانلود شده است، دسترسی نخواهد داشت.
5.6.2. کلاس JApplet
5.6.2.1. Définition
یک برنامه کاربردی میتواند توسط یک مرورگر وب دانلود شود اگر یک نمونه از کلاس java.applet.Applet یا کلاس javax.swing.JApplet باشد. دومی از اولی مشتق شده است، که خود از کلاس Panel مشتق شده است، که خود از کلاس Container مشتق شده است. از آنجایی که یک نمونه از Applet یا JApplet از نوع container است، بنابراین ممکن است حاوی کامپوننتها (Component) مانند دکمهها، چکباکسها، لیستها و غیره باشد. در اینجا چند راهنما در مورد نقش روشهای مختلف آورده شده است:
متد | نقش |
public void destroy(); | نابود کردن نمونهٔ آلتافزار |
public AppletContext getAppletContext(); | زمینهٔ اجرای اپلت را بازیابی میکند (سند HTML که اپلت در آن قرار دارد، اپلتهای دیگر در همان سند و غیره) |
public String getAppletInfo(); | یک رشته حاوی اطلاعات دربارهٔ اپلت را بازمیگرداند |
public AudioClip getAudioClip(URL url); | فایل صوتی مشخصشده توسط URL را بارگذاری میکند |
public AudioClip getAudioClip(URL url, String name); | فایل صوتی مشخصشده توسط URL/name را بارگذاری میکند |
public URL getCodeBase(); | بازگرداندن URL آلتافزار |
عمومی URL getDocumentBase(); | بازگرداندن URL از سند HTML حاوی اپلت |
public Image getImage(URL url); | تصویر مشخصشده توسط URL را بازیابی میکند |
public Image getImage(URL url, String name); | تصویر مشخصشده توسط URL/name را بازیابی میکند |
public String getParameter(String name); | مقدار پارامتر name را که در تگ <applet> سند HTML حاوی اپلت قرار دارد، بازیابی میکند. |
public void init(); | این متد توسط مرورگر زمانی فراخوانی میشود که اپلت برای اولین بار اجرا میشود |
public boolean isActive(); | وضعیت اپلت |
public void play(URL url); | فایل صوتی مشخصشده توسط URL را پخش میکند |
public void play(URL url, String name); | پخش فایل صوتی مشخصشده توسط UR/name |
public void resize(Dimension d); | اندازه قاب اپلت را تعیین میکند |
public void resize(int width, int height); | همانند بالا |
public final void setStub(AppletStub stub); | |
public void showStatus(String msg); | یک پیام را در نوار وضعیت اپلت نمایش میدهد |
public void start(); | این متد هر بار که سند حاوی اپلت نمایش داده میشود، توسط مرورگر فراخوانی میشود |
public void stop(); | این متد توسط مرورگر هر زمان که سند حاوی اپلت به نفع سند دیگری رها شود، فراخوانی میشود (کاربر از URL خارج میشود) |
کلاس JApplet تعدادی بهبود را نسبت به کلاس Applet ارائه کرده است، بهویژه قابلیت شامل شدن کامپوننتهای JMenuBar و c.a.d. موارد منو، که با کلاس Applet امکانپذیر نبود.
5.6.2.2. اجرای یک اپلت: متدهای init، start و stop
وقتی یک مرورگر یک اپلت را بارگذاری میکند، سه متد آن را فراخوانی میکند:
init | این متد زمانی فراخوانی میشود که اپلت برای اولین بار بارگذاری میشود. بنابراین باید شامل inizializاسیونهای لازم برای برنامه باشد. |
start | این متد هرگاه سند حاوی اپلت به سند جاری مرورگر تبدیل شود، فراخوانی میشود. بنابراین، وقتی کاربر یک اپلت را بارگذاری میکند، متدهای init و start به ترتیب اجرا خواهند شد. وقتی کاربر سند را ترک میکند تا سند دیگری را مشاهده کند، متد stop اجرا میشود. وقتی بعداً به آن بازمیگردد، متد start اجرا خواهد شد. |
stop | این متد هر زمان که کاربر سند حاوی اپلت را ترک میکند، فراخوانی میشود. |
برای بسیاری از اپلتها، تنها متد init لازم است. متدهای start و stop تنها در صورتی ضروری هستند که برنامه وظایفی (تراکنشها) را راهاندازی کند که به طور موازی و مداوم اجرا میشوند، اغلب بدون اطلاع کاربر. وقتی کاربر سند را ترک میکند، بخش قابل مشاهده برنامه ناپدید میشود، اما این وظایف پسزمینه به اجرای خود ادامه میدهند. این اغلب غیرضروری است. بنابراین برای متوقف کردن آنها از فراخوانی متد **stop** توسط مرورگر استفاده میکنیم. اگر کاربر به سند بازگردد، برای راهاندازی مجدد آنها از فراخوانی متد **start** توسط مرورگر استفاده میکنیم.
برای مثال، یک اپلت را در نظر بگیرید که در رابط کاربری گرافیکی خود یک ساعت دارد. این ساعت توسط یک وظیفه پسزمینه (ترد) نگهداری میشود. هنگامی که کاربر صفحه اپلت را در مرورگر ترک میکند، ادامه دادن به نمایش ساعت که اکنون نامرئی شده است، بیفایده است: در متد **stop** اپلت، ما تردی را که ساعت را مدیریت میکند، متوقف میکنیم. در متد **start**، آن را مجدداً راهاندازی میکنیم تا وقتی کاربر به صفحه اپلت بازمیگردد، ساعتی را ببیند که بهروز است.
5.6.3. تبدیل یک برنامه گرافیکی به یک اپلت
ما در اینجا فرض میکنیم که این تبدیل امکانپذیر است، یعنی با محدودیتهای اجرای اپلِت مطابقت دارد. یک برنامه با متد main یکی از کلاسهای آن راهاندازی میشود:
چنین برنامهای به صورت زیر به یک اپلت تبدیل میشود:
import java.applet.JApplet;
…
public class application extends JApplet{
…
public void init(){
…
}
…
}// پایان کلاس
لطفاً به نکات زیر توجه کنید:
- کلاس application اکنون از کلاس JApplet ارث میبرد
- متد main با متد init جایگزین شده است.
بهعنوان مثال، بیایید نگاهی دوباره به برنامهای که قبلاً بررسی کردهایم بیندازیم: مدیریت فهرست.

اجزای این پنجره به شرح زیر است:
خیر. | نوع | نام | نقش |
1 | JTextField | txtSaisie | میدان ورودی |
2 | JList | jList1 | لیست قرار گرفته در داخل یک کانتینر jScrollPane1 |
3 | JList | jList2 | فهرست موجود در یک کانتینر jScrollPane2 |
4 | JButton | cmd1To2 | موارد انتخابشده را از لیست ۱ به لیست ۲ منتقل میکند |
5 | JButton | cmd2To1 | معکوس آن را انجام میدهد |
۶ | JButton | cmdRaz1 | فهرست 1 را پاک کنید |
7 | JButton | cmdRaz2 | پاک کردن فهرست ۲ |
ساختار برنامه به شرح زیر بود:
public class interfaceAppli extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**چارچوب را بسازید*/
public interfaceAppli() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
...
txtSaisie.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
txtSaisie_actionPerformed(e);
}
});
...
//Jlist1 در کانتینر jScrollPane1 قرار میگیرد
jScrollPane1.getViewport().add(jList1, null);
//Jlist2 در کانتینر jScrollPane2 قرار داده شده است
jScrollPane2.getViewport().add(jList2, null);
...
}
/**جایگزین شد، تا بتوانیم هنگام بستن پنجره خارج شویم*/
protected void processWindowEvent(WindowEvent e) {
...
}
void txtSaisie_actionPerformed(ActionEvent e) {
.............
}//کلاس
void cmdRaz1_actionPerformed(ActionEvent e) {
// فهرست 1 را پاک کنید
v1.removeAllElements();
}//cmd Reset1
void cmdRaz2_actionPerformed(ActionEvent e) {
// فهرست ۲ را پاک کنید
v2.removeAllElements();
}///cmd Clear2
برای تبدیل کلاس appli به applet، مراحل زیر را انجام دهید:
- کلاس قبلی interfaceAppli را طوری اصلاح کنید که دیگر از JFrame ارثبری نکند، بلکه از JApplet ارثبری کند:
- دستور تعیین عنوان پنجره JFrame را حذف کنید. یک اپلِت JApplet نوار عنوان ندارد.
- سازنده را به یک متد (init) تبدیل کنید و در داخل این متد، رسیدگی به رویدادهای پنجره (WindowListener, ...) را حذف کنید. یک اپلکت یک کانتینر است که نمیتوان آن را تغییر اندازه داد یا بست.
/**ساخت فریم*/
public init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
- روش processWindowEvent باید حذف یا غیرفعال شود
/**جایگزین شده، تا بتوانیم هنگام بستن پنجره خارج شویم*/
//protected void processWindowEvent(WindowEvent e) {
// super.processWindowEvent(e);
// if (e.getID() == WindowEvent.WINDOW_CLOSING) {
// System.exit(0);
// }
// }
بهعنوان مثال، در اینجا کد کامل اپلت آورده شده است، به استثنای بخشی که بهطور خودکار توسط JBuilder تولید میشود.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceAppli extends JApplet {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JLabel jLabel2 = new JLabel();
JLabel jLabel3 = new JLabel();
JTextField txtSaisie = new JTextField();
JButton cmd1To2 = new JButton();
JButton cmd2To1 = new JButton();
DefaultListModel v1=new DefaultListModel();
DefaultListModel v2=new DefaultListModel();
JList jList1 = new JList(v1);
JList jList2 = new JList(v2);
JScrollPane jScrollPane1 = new JScrollPane();
JScrollPane jScrollPane2 = new JScrollPane();
JButton cmdRaz1 = new JButton();
JButton cmdRaz2 = new JButton();
JLabel jLabel4 = new JLabel();
/**چارچوب را بسازید*/
public void init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}//interfaceAppli
/**ابتداییسازی مؤلفه*/
private void jbInit() throws Exception {
//setIconImage(Toolkit.getDefaultToolkit().createImage(interfaceAppli.class.getResource("[Votre icône]")));
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(400, 308));
// this.setTitle("JList");
jScrollPane1.setBounds(new Rectangle(37, 133, 124, 101));
jScrollPane2.setBounds(new Rectangle(232, 132, 124, 101));
.............
}
void txtSaisie_actionPerformed(ActionEvent e) {
// متن وارد شده اعتبارسنجی شده است
// متن وارد شده با حذف فاصلههای ابتدایی و انتهایی بازیابی میشود
String texte=txtSaisie.getText().trim();
// اگر خالی باشد، آن را نمیخواهیم
if(texte.equals("")){
// پیام خطا
JOptionPane.showMessageDialog(this,"Vous devez taper un texte",
"Erreur",JOptionPane.WARNING_MESSAGE);
//پایان
return;
}//اگر
// اگر خالی نباشد، آن را به مقادیر لیست 1 اضافه کنید
v1.addElement(texte);
// و فیلد ورودی را پاک کنید
txtSaisie.setText("");
}
void cmd1To2_actionPerformed(ActionEvent e) {
//انتقال موارد انتخابشده از لیست ۱ به لیست ۲
transfert(jList1,jList2);
}//cmd1To2
private void transfert(JList L1, JList L2){
//انتقال موارد انتخابشده از فهرست 1 به فهرست 2
//بازیابی آرایهٔ شاخصها برای موارد انتخابشده در L1
int[] indices=L1.getSelectedIndices();
// آیا کاری با آن دارد؟
if (indices.length==0) return;
// مقادیر را از L1 بازیابی میکند
DefaultListModel v1=(DefaultListModel)L1.getModel();
//و آنهایی از L2
DefaultListModel v2=(DefaultListModel)L2.getModel();
for(int i=indices.length-1;i>=0;i--){
// ما مقادیر انتخابشده از L1 را به L2 اضافه میکنیم
v2.addElement(v1.elementAt(indices[i]));
// عناصر از L1 که به L2 کپی شدهاند باید از L1 حذف شوند
v1.removeElementAt(indices[i]);
}//برای
}//انتقال
private void affiche(String message){
//پیامی را نمایش میدهد
JOptionPane.showMessageDialog(this,message,
"Suivi",JOptionPane.INFORMATION_MESSAGE);
}//نمایش میدهد
void cmd2To1_actionPerformed(ActionEvent e) {
//آیتمهای انتخابشده را از jList2 به jList1 منتقل میکند
transfert(jList2,jList1);
}//cmd2TO1
void cmdRaz1_actionPerformed(ActionEvent e) {
// پاک کردن لیست ۱
v1.removeAllElements();
}//فرمان Raz1
void cmdRaz2_actionPerformed(ActionEvent e) {
// فهرست خالی ۲
v2.removeAllElements();
}//cmd Clear2
}//کلاس
کد منبع این اپلِت قابل کامپایل است. ما این کار را در اینجا با استفاده از JDK انجام میدهیم، بدون JBuilder.
E:\data\serge\Jbuilder\interfaces\JApplets\1>javac.bat interfaceAppli.java
E:\data\serge\Jbuilder\interfaces\JApplets\1>dir
12/06/2002 16:40 6 148 interfaceAppli.java
12/06/2002 16:41 527 interfaceAppli$1.class
12/06/2002 16:41 525 interfaceAppli$2.class
12/06/2002 16:41 525 interfaceAppli$3.class
12/06/2002 16:41 525 interfaceAppli$4.class
12/06/2002 16:41 525 interfaceAppli$5.class
12/06/2002 16:41 4 759 interfaceAppli.class
این برنامه را میتوان با استفاده از برنامه AppletViewer از JDK آزمایش کرد، که امکان اجرای اپلکتها یا یک مرورگر را فراهم میکند. برای این کار، باید سند HTML appli.htm را ایجاد کنید که شامل اپلت خواهد بود:
<html>
<head>
<title>listes swing</title>
</head>
<body>
<applet
code="interfaceAppli.class"
width="400"
height="300">
</applet>
</body>
</html>
این یک سند استاندارد HTML است، اگر نه به خاطر وجود تگ applet. این تگ با سه پارامتر استفاده شده است:
code="interfaceAppli.class" | نام کلاس کامپایلشده JAVA که برای اجرای اپلِت بارگذاری میشود |
width="400" | عرض قاب اپلت در داخل سند |
height="300" | ارتفاع قاب اپلِت در داخل سند |
پس از نوشتن فایل appli.htm، میتوان آن را با استفاده از برنامه appletviewer از JDK یا از طریق یک مرورگر وب بارگذاری کرد. در یک پنجره DOS، دستور زیر را در پوشهای که حاوی فایل appli.htm است تایپ کنید:
appletviewer appli.htm
ما در اینجا فرض میکنیم که دایرکتوری حاوی فایل اجرایی appletviewer.exe در دایرکتوری PATH نشان داده شده در پنجره DOS قرار دارد؛ در غیر این صورت، باید مسیر کامل فایل اجرایی appletviewer.exe را مشخص کنید. پنجره زیر ظاهر میشود:

اجرای اپلِت را با استفاده از گزینه Applet/Quitter متوقف کنید. اکنون بیایید اپلت را با استفاده از یک مرورگر وب آزمایش کنیم. مرورگر باید از یک ماشین مجازی جاوا 2 استفاده کند تا بتواند کامپوننتهای Swing را نمایش دهد. تا همین اواخر (۲۰۰۱)، این الزام یک مشکل بود زیرا شرکت Sun نسخههای JDK را تولید میکرد که فروشندگان مرورگر در پذیرش آنها بسیار کند عمل میکردند. سرانجام شرکت Sun با ارائه برنامهای به نام «پلاگین جاوا» به کاربران، این مشکل را حل کرد. این برنامه به Internet Explorer و Netscape Navigator امکان میدهد تا از جدیدترین نسخههای JRE تولید شده توسط Sun (JRE = محیط اجرایی جاوا) استفاده کنند. آزمایشهای زیر با استفاده از IE نسخهٔ ۵.۵ همراه با افزونهٔ جاوا ۱.۴ انجام شدند.
یک روش برای آزمایش اپلت interfaceAppli.class این است که فایل HTML appli.htm را با دوبار کلیک کردن مستقیماً در مرورگر بارگذاری کنید. مرورگر سپس صفحه HTML و اپلِت آن را بدون نیاز به وبسرور نمایش خواهد داد:

از URL (1) میتوان دید که فایل مستقیماً در مرورگر بارگذاری شده است. در مثال زیر، فایل appli.htm از یک سرور وب آپاچی که روی پورت 81 در ماشین محلی در حال اجرا است، درخواست شده است:

5.6.4. گزینه قالببندی <applet> در یک سند HTML
ما دیدهایم که در یک سند HTML، اپلت توسط دستور قالببندی (برچسب) <applet> ارجاع میشود. این دستور میتواند پارامترهای مختلفی داشته باشد:
<applet
code=
width=
height=
codebase=
align=
hspace=
vspace=
alt=
>
<param name1=nom1 value=val1>
<param name2=nom2 value=val2>
texte
>
</applet>
پارامترها معانی زیر را دارند:
پارامتر | معنی |
code | الزامی – نام فایل .class که باید اجرا شود |
width | الزامی – عرض اپلت در داخل سند |
height | الزامی – ارتفاع … |
codebase | اختیاری – URL مسیر دایرکتوری حاوی اپلت قابل اجرا. اگر 'codebase' مشخص نشود، اپلت در دایرکتوری سند HTML که به آن ارجاع داده شده است جستجو خواهد شد |
align | اختیاری – موقعیتیابی (LEFT, RiGHT, CENTER) آلت در داخل سند |
hspace | اختیاری – حاشیه افقی اطراف اپلت، بیانشده به پیکسل |
vspace | اختیاری – حاشیه عمودی اطراف اپلت، بیانشده به پیکسل |
alt | اختیاری – متنی که در صورت عدم بارگذاری اپلت توسط مرورگر، به جای آن نمایش داده شود |
param | اختیاری – پارامتر ارسالشده به اپلت که نام (name) و مقدار (value) آن را مشخص میکند. اپلت میتواند مقدار پارامتر 'name1' را با استفاده از 'val1=getParameter("name1")' بازیابی کند. میتوانید هر تعداد پارامتر که میخواهید استفاده کنید |
texte | اختیاری – توسط هر مرورگری که قادر به اجرای یک اپلِت نیست، نمایش داده میشود، برای مثال به این دلیل که ماشین مجازی جاوا ندارد. |
بیایید برای روشن شدن نحوه ارسال پارامترها به یک اپلت، یک مثال بزنیم:
<html>
<head>
<title>paramètres applet</title>
</head>
<body>
<applet code="interfaceParams.class" width="400" height="300">
<param name="param1" value="val1">
<param name="param2" value="val2">
</applet>
</body>
</html>
کد جاوا برای اپلت interfaceParams همانطور که در بالا توضیح داده شد تولید شد. ما یک برنامه JBuilder ساختیم و سپس چند تغییر ذکرشده در بالا را اعمال کردیم:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class interfaceParams extends JApplet {
JPanel contentPane;
JScrollPane jScrollPane1 = new JScrollPane();
JLabel jLabel1 = new JLabel();
DefaultListModel params=new DefaultListModel();
JList lstParams = new JList(params);
//ساخت قاب
public void init() {
// enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// ابتکارات دیگر
moreInit();
}
// ابتداییسازیها
public void moreInit(){
//مقادیر پارامترهای اپلت را نمایش میدهد
params.addElement("nom=param1 valeur="+getParameter("param1"));
params.addElement("nom=param2 valeur="+getParameter("param2"));
}//initهای بیشتر
//کامپوننت را инициалиزه کنید
private void jbInit() throws Exception {
............
this.setSize(new Dimension(205, 156));
//this.setTitle("پارامترهای آپلِت");
jScrollPane1.setBounds(new Rectangle(19, 53, 160, 73));
............
}
}
خروجی برای AppletViewer:

5.6.5. دسترسی به منابع راه دور از یک اپلت
بسیاری از برنامهها نیاز دارند از اطلاعات موجود در فایلها یا پایگاههای داده استفاده کنند. ما اشاره کردهایم که یک اپلت به منابع ماشینی که روی آن اجرا میشود دسترسی ندارد. این یک اقدام منطقی است. در غیر این صورت، میتوان یک اپلت نوشت که بر هارد دیسک کسانی که آن را بارگذاری میکنند «جاسوسی» کند. با این حال، اپلت به منابعی که از سرور دانلود شده است، مانند فایلها، دسترسی دارد. این چیزی است که اکنون به آن خواهیم پرداخت.
5.6.5.1. کلاس URL
هر برنامه جاوا میتواند با استفاده از کلاس java.net.URL (URL = مکانیاب یکنواخت منبع) یک فایل را که روی یک ماشین در شبکه قرار دارد، بخواند. یک URL یک منبع شبکه، ماشینی که روی آن قرار دارد، و پروتکل ارتباطی و پورت مورد استفاده برای بازیابی آن را به شکل زیر مشخص میکند:
پروتکل:پورت//ماشین/فایل
بنابراین، URL http://www.ibm.com/index.html به فایل index.html روی ماشین www.ibm.com اشاره میکند. این فایل از طریق پروتکل http قابل دسترسی است. پورت مشخص نشده است: مرورگر از پورت ۸۰ استفاده خواهد کرد که پورت پیشفرض سرویس HTTP است.
بیایید به برخی از عناصر کلاس URL نگاهی بیندازیم:
public URL(String spec) | یک نمونه از URL را از یک رشته به شکل «پروتکل:پورت//ماشین/فایل» ایجاد میکند – در صورتی که نحو رشته با URL مطابقت نداشته باشد، یک استثنا پرتاب میکند |
public String getFile() | میدان 'file' را از رشته «protocol:port//machine/file» برای URL بازیابی میکند |
public String getHost() | میدان 'machine' را از رشته «protocol:port//machine/file» در URL بازیابی میکند |
public String getPort() | میدان پورت را از رشته "protocol:port//machine/file" در URL بازیابی میکند |
public String getProtocol() | میدان پروتکل را از رشته "protocol:port//machine/file" در URL بازیابی میکند |
public URLConnection openConnection() | یک اتصال به ماشین راه دور getHost() را روی پورت آن getPort() با استفاده از پروتکل getProtocol() برای خواندن فایل getFile() باز میکند. در صورتی که اتصال برقرار نشود، یک استثنا پرتاب میکند |
public final InputStream openStream() | کوتهراهی برای openConnection().getInputStream(). یک جریان ورودی را بهدست میآورد که از آن میتوان محتوای فایل getFile() را خواند. اگر نتوان جریان را بهدست آورد، یک استثنا پرتاب میکند |
public String toString() | هویت نمونه URL را نمایش میدهد |
در اینجا دو متد مورد توجه وجود دارد:
- public URL(String spec) برای مشخص کردن فایلی که باید پردازش شود
- public final InputStream openStream() برای پردازش آن
5.6.5.2. یک مثال کنسولی
ما قصد داریم یک برنامهٔ جاوا بدون رابط کاربری گرافیکی بنویسیم که برای نمایش محتویات یک فایل URL که بهعنوان پارامتر به آن ارسال میشود، روی صفحه طراحی شده است. یک مثال از فراخوانی ممکن است به شکل زیر باشد:
برنامه نسبتاً ساده است:
import java.net.*; //برای کلاس URL
import java.io.*; //برای استریمها
public class urlcontenu{
// محتوای URL را که بهعنوان آرگومان ارسال شده است نمایش میدهد
//این محتوا باید متن باشد تا قابل خواندن باشد
public static void main (String arg[]){
//بررسی آرگومانها
if(arg.length==0){
System.err.println("Syntaxe pg url");
System.exit(0);
}
try{
// ایجاد URL
URL url=new URL(arg[0]);
// خواندن محتوا
try{
// ایجاد جریان ورودی
BufferedReader is=new BufferedReader(new InputStreamReader(url.openStream()));
try{
//خواندن خطوط متن از جریان ورودی
String ligne;
while((ligne=is.readLine())!=null)
System.out.println(ligne);
} catch (Exception e){
System.err.println("Erreur lecture : " +e);
}
finally{
try { is.close(); } catch (Exception e) {}
}
} catch (Exception e){
System.err.println("Erreur openStream : " +e);
}
} catch (Exception e){
System.err.println("Erreur création URL : " +e);
}
}//پایان کلاس اصلی
}//پایان کلاس
پس از بررسی وجود یک آرگومان، ما تلاش میکنیم با استفاده از آن یک URL ایجاد کنیم:
// ایجاد URL
URL url=new URL(arg[0]);
این ایجاد ممکن است در صورتی که آرگومان با نحو URL protocole:port//machine/fichier مطابقت نداشته باشد، ناموفق باشد. اگر یک URL از نظر نحوی صحیح داشته باشیم، سعی میکنیم یک استریم ورودی ایجاد کنیم که بتوانیم از آن خطوط متن را بخوانیم. جریان ورودی ارائهشده توسط تابع URL URL.openStream() یک جریان از نوع InputStream را بازمیگرداند که یک جریان مبتنی بر کاراکتر است: خواندن به صورت کاراکتر به کاراکتر انجام میشود و شما باید خطوط را خودتان تشکیل دهید. برای خواندن خطوط متن، باید از متد readLine کلاسهای BufferedReader یا DataInputStream.On استفاده کنید؛ در اینجا، BufferedReader انتخاب شده است. تنها کاری که باقی مانده تبدیل جریان InputStream از URL به یک جریان BufferedReader است. این کار با ایجاد یک جریان واسط، InputStreamReader انجام میشود:
BufferedReader is=new BufferedReader(new InputStreamReader(url.openStream()));
ایجاد این جریان ممکن است با شکست مواجه شود. ما با خطای متناظر آن مقابله میکنیم. پس از بهدست آمدن جریان، تنها کاری که باقی میماند خواندن خطوط متن از آن و نمایش آنها بر روی صفحه است.
String ligne;
while((ligne=is.readLine())!=null)
System.out.println(ligne);
در اینجا نیز، خواندن استریم ممکن است یک استثنا را فعال کند که باید مدیریت شود. در اینجا مثالی از اجرای برنامه آورده شده است که به یک URL محلی نیاز دارد:
E:\data\serge\Jbuilder\interfaces\JApplets\3>java urlcontenu http://localhost
<html>
<head>
<title>Bienvenue dans le Serveur Web personnel</title>
</head>
<body bgcolor="#FFFFFF" link="#0080FF" vlink="#0080FF"
topmargin="0" leftmargin="0">
<table border="0" cellpadding="0" cellspacing="0" width="100%"
bgcolor="#000000">
............
</table>
</center></div></td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
5.6.5.3. یک مثال گرافیکی
رابط کاربری گرافیکی به شرح زیر خواهد بود:

شماره | نام | نوع | نقش |
۱ | txtURL | JTextField | URL – لطفاً بخوانید |
2 | btnCharger | JButton | دکمه برای شروع پخش URL |
3 | JScrollPane | JScrollPane | پنل پیمایش |
4 | lstURL | JList | فهرست نمایشدهنده محتویات URL درخواستی |
هنگام اجرا، خروجی مشابه خروجی برنامه کنسول است:

کد مربوطه از برنامه به شرح زیر است:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.net.*;
import java.io.*;
public class interfaceURL extends JFrame {
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JTextField txtURL = new JTextField();
JButton btnCharger = new JButton();
JScrollPane jScrollPane1 = new JScrollPane();
DefaultListModel lignes=new DefaultListModel();
JList lstURL = new JList(lignes);
//چارچوب را بسازید
public interfaceURL() {
..............
}
//کامپوننت را راهاندازی کنید
private void jbInit() throws Exception {
..............
}
//جایگزین شد، بنابراین میتوانیم هنگام بستن پنجره خارج شویم
protected void processWindowEvent(WindowEvent e) {
...................
}
void txtURL_caretUpdate(CaretEvent e) {
//وضعیت دکمهٔ Load را تنظیم میکند
btnCharger.setEnabled(! txtURL.getText().trim().equals(""));
}
void btnCharger_actionPerformed(ActionEvent e) {
//محتویات URL را در لیست نمایش میدهد
try{
afficherURL(txtURL.getText().trim());
}catch(Exception ex){
//خطا را نمایش میدهد
JOptionPane.showMessageDialog(this,"Erreur : " + ex.getMessage(),"Erreur",JOptionPane.ERROR_MESSAGE);
}//try-catch
}
private void afficherURL(String strURL) throws Exception {
//محتویات URL و strURL را در لیست نمایش میدهد
// هیچ استثنایی بهطور خاص مدیریت نمیشود. آنها صرفاً منتقل میشوند
// ایجاد URL
URL url=new URL(strURL);
// ایجاد جریان ورودی
BufferedReader IN=new BufferedReader(new InputStreamReader(url.openStream()));
//خواندن خطوط متنی از جریان ورودی
String ligne;
while((ligne=IN.readLine())!=null)
lignes.addElement(ligne);
//بستن جریان خواندن
IN.close();
}
}
5.6.5.4. یک اپلت
برنامهٔ گرافیکی قبلی به یک اپلت تبدیل شده است، همانطور که در چندین مورد نشان داده شده است. اپلت در مستندی به شناسهٔ HTML appliURL.htm جاسازی شده است:
<html>
<head>
<title>Applet lisant une URL</title>
</head>
<body>
<h1>Applet lisant une URL</h1>
<applet
code="appletURL.class"
width="400"
height="300"
>
</applet>
</body>
</html>

در مثال بالا، مرورگر http://localhost:81/Japplets/2/appliURL.htm را از یک وبسرور apache که روی پورت 81 در حال اجرا بود، درخواست کرد. سپس اپلت در مرورگر نمایش داده شد. در داخل اپلت، مجدداً URL http://localhost:81/Japplets/2/appliURL.htm را درخواست کردیم تا تأیید کنیم که واقعاً فایلی را که ایجاد کرده بودیم دریافت میکنیم. اکنون بیایید سعی کنیم یک URL را بارگذاری کنیم که به ماشین صادرکننده اپلت تعلق ندارد (در این مورد، localhost):

تلاش برای بارگذاری URL رد شد. این موضوع محدودیت مربوط به اپلکتها را برجسته میکند: آنها فقط میتوانند به منابع شبکه روی دستگاهی که از آن دانلود شدهاند دسترسی داشته باشند. راهی برای دور زدن این محدودیت برای اپلت وجود دارد که آن واگذاری درخواستهای شبکه به یک برنامه سرور مستقر در دستگاهی است که اپلت از آن دانلود شده است. این برنامه درخواستهای شبکه را از طرف اپلت انجام داده و نتایج را به آن بازمیگرداند. این برنامه به عنوان یک برنامه واسطه (relay programme) شناخته میشود.
5.7. اپلت IMPOTS
اکنون قصد داریم برنامه گرافیکی IMPOTS را به یک اپلِت تبدیل کنیم. این موضوع از اهمیت ویژهای برخوردار است: این برنامه برای هر کاربر اینترنتی که مرورگر و افزونه جاوا 1.4 داشته باشد، در دسترس قرار خواهد گرفت (به دلیل کامپوننت JSpinner). بنابراین برنامه ما در سطح جهانی در دسترس قرار خواهد گرفت... این تغییر به چیزی بیش از تبدیل استاندارد یک برنامه گرافیکی به یک اپلِت نیاز دارد. این برنامه از یک گزینه منو به نام Initialiser استفاده میکند که برای خواندن محتویات یک فایل محلی طراحی شده است. با این حال، اگر یک برنامه وب را در نظر بگیریم، میبینیم که این رویکرد دیگر کار نمیکند:

واضح است که دادههای تعریفکننده مقیاسهای مالیاتی روی سرور وب قرار خواهند داشت و نه روی هر رایانه مشتری به طور جداگانه. فایلی که باید از سرور وب خوانده شود، در همان پوشه اپلت قرار داده خواهد شد و گزینه Initialiser باید آن را از آنجا بازیابی کند. مثالهای قبلی نشان دادهاند که چگونه این کار را انجام دهیم. علاوه بر این، برای انتخاب محلی فایل داده، از کامپوننت JFileChooser استفاده کرده بودیم که در اینجا دیگر مورد نیاز نیست.
سند HTML حاوی اپلت به شرح زیر خواهد بود:
<html>
<head>
<title>Applet de calcul d'impôts</title>
</head>
<body>
<h2>Calcul d'impôts</h2>
<applet
code="appletImpots.class"
width="320"
height="270"
>
<param name="data" value="impots.txt">
به پارامتر data توجه کنید که مقدار آن نام فایلی است که حاوی دادههای جدول مالیاتی میباشد. سند HTML، کلاس appletImpots، کلاس impots و فایل impots.txt همگی در یک پوشه روی سرور وب قرار دارند:
E:\data\serge\web\JApplets\impots>dir
12/06/2002 13:24 247 impots.txt
13/06/2002 10:17 654 appletImpots$2.class
13/06/2002 10:17 653 appletImpots$3.class
13/06/2002 10:17 653 appletImpots$4.class
13/06/2002 10:17 651 appletImpots$5.class
13/06/2002 10:06 651 appletImpots$6.class
13/06/2002 10:17 8 655 appletImpots.class
13/06/2002 10:17 657 appletImpots$1.class
13/06/2002 10:24 286 appletImpots.htm
13/06/2002 10:17 1 305 impots.class
کد این اپلت به شرح زیر است (ما تنها تغییرات را نسبت به برنامهٔ گرافیکی برجسته کردهایم):
...........
import java.net.*;
import java.applet.Applet;
public class appletImpots extends JApplet {
// اجزای پنجره
JPanel contentPane;
............................
//ویژگیهای کلاس
double[] limites=null;
double[] coeffr=null;
double[] coeffn=null;
impots objImpots=null;
String urlDATA=null;
//ساخت فریم
public void init() {
//enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
// ابتکارات دیگر
moreInit();
}
// ابتدایسازی فرم
private void moreInit(){
// غیرفعال بودن منوی «محاسبه»
mnuCalculer.setEnabled(false);
................
// بازیابی نام فایل جدول مالیاتی
String nomFichier=getParameter("data");
// خطا؟
if(nomFichier==null){
// پیام خطا
txtStatus.setText("Le paramètre data de l'applet n'a pas été initialisé");
// غیرفعال کردن گزینه «ابتداییسازی»
mnuInitialiser.setEnabled(false);
//پایان
return;
}//اگر
// تنظیم URL برای دادهها
urlDATA=getCodeBase()+"/"+nomFichier;
}//moreInit
//کامپوننت را راهاندازی کنید
private void jbInit() throws Exception {
...................
}
void mnuQuitter_actionPerformed(ActionEvent e) {
//خروج از برنامه
System.exit(0);
}
void mnuInitialiser_actionPerformed(ActionEvent e) {
// بارگذاری فایل داده
try{
// خواندن دادهها
lireDATA();
// ایجاد شیء 'impots'
objImpots=new impots(limites,coeffr,coeffn);
................
}
private void lireDATA() throws Exception {
// جدولهای داده
ArrayList aLimites=new ArrayList();
ArrayList aCoeffR=new ArrayList();
ArrayList aCoeffN=new ArrayList();
String[] champs=null;
// باز کردن فایل در حالت فقط خواندنی
BufferedReader IN=new BufferedReader(new InputStreamReader(new URL(urlDATA).openStream()));
// خواندن خط به خط فایل
....................
}
void mnuCalculer_actionPerformed(ActionEvent e) {
//محاسبه مالیات
......................
}
void txtSalaire_caretUpdate(CaretEvent e) {
..........
}
void mnuEffacer_actionPerformed(ActionEvent e) {
...............
}
}
ما در اینجا تنها در مورد تغییراتی که از این واقعیت ناشی میشود که فایل دادهای که باید خوانده شود اکنون روی یک ماشین از راه دور به جای یک ماشین محلی قرار دارد، توضیح میدهیم:
نام فایل داده URL که باید خوانده شود، با استفاده از کد زیر به دست میآید:
//بازیابی نام فایل جدول مالیات
String nomFichier=getParameter("data");
// خطا؟
if(nomFichier==null){
// پیام خطا
txtStatus.setText("Le paramètre data de l'applet n'a pas été initialisé");
//غیرفعال کردن گزینه «Initialise»
mnuInitialiser.setEnabled(false);
//پایان
return;
}//اگر
// تنظیم URL برای دادهها
urlDATA=getCodeBase()+"/"+nomFichier;
بیایید به یاد داشته باشیم که نام فایل «impots.txt» به پارامتر data اپلِت ارسال شده است:
بنابراین کد بالا با بازیابی مقدار پارامتر data آغاز میشود، در حالی که هرگونه خطایی را که ممکن است رخ دهد، مدیریت میکند. اگر URL سند HTML حاوی اپلت http://localhost:81/JApplets/impots/appletImpots.htm باشد، URL برای فایل impots.txt برابر خواهد بود با http://localhost:81/JApplets/impots/impots.txt. ما باید نام این URL را بسازیم. متد getCodeBase() اپلت، URL پوشهای را بازمیگرداند که سند HTML حاوی اپلت از آن بازیابی شده است، بنابراین در مثال ما http://localhost:81/JApplets/impots. دستورالعمل زیر به ما امکان میدهد تا URL را برای فایل داده بسازیم:
روش lireFichier() که محتویات URL و urlData را میخواند، شامل ایجاد جریان ورودی است که امکان خواندن دادهها را فراهم میکند:
// باز کردن فایل برای خواندن
BufferedReader IN=new BufferedReader(new InputStreamReader(new URL(urlDATA).openStream()));
از این نقطه به بعد، دیگر نمیتوان تشخیص داد که دادهها از یک فایل محلی هستند یا از یک فایل راه دور. در اینجا مثالی از اجرای این اپلت آورده شده است:

5.8. نتیجهگیری
این فصل ارائه کرده است
- مقدمهای بر ساخت رابطهای کاربری گرافیکی با JBuilder
- رایجترین کامپوننتهای Swing
- ایجاد اپلکتها
شایان ذکر است که
- کدی که توسط JBuilder تولید میشود را میتوان بهصورت دستی نوشت. پس از بهدستآوردن این کد به هر نحو ممکن، یک JDK ساده برای اجرای آن کافی است و JBuilder دیگر ضروری نخواهد بود.
- استفاده از ابزاری مانند JBuilder میتواند به افزایش چشمگیر بهرهوری منجر شود:
- اگرچه نوشتن دستی کدی که توسط JBuilder تولید شده است امکانپذیر است، اما این کار میتواند بسیار وقتگیر باشد و فایده چندانی نداشته باشد، زیرا منطق برنامه معمولاً در جای دیگری قرار دارد.
- کد تولیدشده میتواند آموزنده باشد. مطالعه و بررسی آن راه خوبی برای کشف برخی روشها و ویژگیهای کامپوننتهایی است که برای اولین بار از آنها استفاده میکنید.
- JBuilder چند سکویی است. بنابراین هنگام جابجایی بین پلتفرمها دانش خود را حفظ میکنید. توانایی نوشتن برنامههایی که هم روی ویندوز و هم روی لینوکس اجرا میشوند، البته عاملی بسیار مهم در بهرهوری است. با این حال، این به خودِ جاوا مربوط است و نه به JBuilder.
5.9. JBuilder روی لینوکس
تمام مثالهای قبلی روی ویندوز ۹۸ آزمایش شدهاند. ممکن است این سؤال پیش بیاید که آیا برنامههای نوشته شده به همین شکل برای لینوکس قابل حمل هستند یا خیر. به شرطی که ماشین لینوکس مورد نظر، کلاسهای مورد استفاده توسط برنامههای مختلف را داشته باشد، پاسخ مثبت است. برای مثال، اگر JBuilder را روی لینوکس نصب کرده باشید، کلاسهای لازم از قبل روی سیستم شما موجود هستند. در اینجا، بهعنوان مثال، خروجی اجرای یکی از برنامههای ما روی کامپوننت JList با JBuilder 4 در لینوکس را مشاهده میکنید:
در زیر، نصب JBuilder 4 Foundation روی یک سیستم لینوکس را تشریح میکنیم. نصب آن روی سیستم Win9x هیچ مشکلی ندارد و مشابه روندی است که در ادامه توضیح داده شده است. نصب نسخههای بعدی ممکن است متفاوت باشد، اما این سند ممکن است همچنان اطلاعات مفیدی ارائه دهد.
JBuilder در وبسایت Inprise به آدرس http://www.inprise.com/jbuilder در دسترس است.

این صفحه حاوی لینکهایی برای ویندوز و لینوکس و غیره است. اکنون نصب JBuilder را روی یک ماشین لینوکس که رابط گرافیکی KDE را اجرا میکند، شرح خواهیم داد.
وقتی روی لینک «JBuilder 4 for Linux» کلیک میکنید، یک فرم ظاهر میشود. آن را پر کنید تا دو فایل دریافت کنید:
jb4docs_fr.tar.gz: مستندات و مثالهای JBuilder 4
jb4fndlinux_fr.tar.gz: JBuilder 4 Foundation. این نسخه محدودی از JBuilder 4 تجاری است، اما برای اهداف آموزشی کافی است.
یک کلید فعالسازی برای نرمافزار از طریق ایمیل برای شما ارسال خواهد شد. این کلید به شما امکان استفاده از JBuilder 4 را میدهد و در اولین بار استفاده از نرمافزار مورد نیاز خواهد بود. اگر این کلید را گم کنید، میتوانید به آدرس اینترنتی بالا بازگردید و پیوند «دریافت کلید فعالسازی خود» را دنبال کنید. اکنون فرض میکنیم که شما root هستید و در دایرکتوری حاوی دو فایل tar.gz که در بالا ذکر شد، قرار دارید. دو فایل را از حالت فشرده خارج کنید:
[ls -l]
drwxr-xr-x 3 nobody nobody 4096 oct 10 2000 docs
drwxr-xr-x 3 nobody nobody 4096 déc 5 13:00 foundation
[ls -l foundation]
-rw-r--r-- 1 nobody nobody 1128 déc 5 13:00 deploy.txt
-rwxr-xr-x 1 nobody nobody 69035365 déc 5 13:00 fnd_linux_install.bin
drwxr-xr-x 2 nobody nobody 4096 déc 5 13:00 images
-rw-r--r-- 1 nobody nobody 15114 déc 5 13:00 index.html
-rw-r--r-- 1 nobody nobody 23779 déc 5 13:00 license.txt
-rw-r--r-- 1 nobody nobody 75739 déc 5 13:00 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 déc 5 13:00 whatsnew.html
[ls -l docs]
-rw-r--r-- 1 nobody nobody 1128 oct 10 2000 deploy.txt
-rwxr-xr-x 1 nobody nobody 40497874 oct 10 2000 doc_install.bin
drwxr-xr-x 2 nobody nobody 4096 oct 10 2000 images
-rw-r--r-- 1 nobody nobody 9210 oct 10 2000 index.html
-rw-r--r-- 1 nobody nobody 23779 oct 10 2000 license.txt
-rw-r--r-- 1 nobody nobody 75739 oct 10 2000 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 oct 10 2000 whatsnew.html
در هر دو پوشهٔ ایجادشده، فایل .bin فایل نصب است. علاوه بر این، در هر پوشه با استفاده از یک مرورگر وب، فایل index.html را باز کنید. این فایلها دستورالعملهایی برای نصب هر دو محصول ارائه میدهند. بیایید با نصب JBuilder Foundation شروع کنیم:
اولین صفحه نصب ظاهر میشود. صفحات بسیار بیشتری به دنبال آن خواهند آمد:

تأیید کنید. یک صفحهٔ توضیحی بعدی نمایش داده خواهد شد:

[suivant] را وارد کنید.

قرارداد مجوز را بپذیرید و [suivant] را وارد کنید.

مکان پیشنهادی نصب JBuilder را بپذیرید (آن را یادداشت کنید، زیرا بعداً به آن نیاز خواهید داشت) و [suivant] را وارد کنید. نصب سریع است.

ما برای یک تست اولیه آمادهایم. در KDE، مدیر فایل را اجرا کنید تا به دایرکتوری اجراییهای JBuilder بروید: /opt/jbuilder4/bin (اگر JBuilder را در /opt/jbuilder4 نصب کردهاید):

روی آیکون jbuilder در بالا کلیک کنید. از آنجا که این اولین باری است که از JBuilder استفاده میکنید، باید کلید فعالسازی خود را وارد کنید:

میدانهای Nom و Société را پر کنید. برای وارد کردن کلید فعالسازی خود روی [Ajouter] کلیک کنید. لطفاً توجه داشته باشید که این کلید باید از طریق ایمیل برای شما ارسال شده باشد و اگر آن را گم کردهاید، میتوانید آن را از URL محل دانلود JBuilder 4 بازیابی کنید (به ابتدای فرایند نصب مراجعه کنید). پس از پذیرش کلید فعالسازی شما، شرایط مجوز برایتان یادآوری خواهد شد:

با وارد کردن OK، به پنجره ورود اطلاعات که قبلاً دیدهاید بازخواهید گشت:

برای تکمیل این مرحله، OK را وارد کنید؛ این مرحله تنها در اولین بار اجرای برنامه انجام میشود. سپس محیط توسعه JBuilder ظاهر خواهد شد:

از JBuilder خارج شوید تا مستندات را اکنون نصب کنید. این کار تعدادی فایل را نصب میکند که در راهنمای JBuilder استفاده خواهند شد، که در حال حاضر ناقص است. به دایرکتوریای که فایلهای JBuilder را در آن استخراج کردهاید بازگردید tar.gz. برنامه نصب در دایرکتوری docs قرار دارد. به آن بروید:
[cd docs]
[ls -l]
-rw-r--r-- 1 nobody nobody 1128 oct 10 2000 deploy.txt
-rwxr-xr-x 1 nobody nobody 40497874 oct 10 2000 doc_install.bin
drwxr-xr-x 2 nobody nobody 4096 oct 10 2000 images
-rw-r--r-- 1 nobody nobody 9210 oct 10 2000 index.html
-rw-r--r-- 1 nobody nobody 23779 oct 10 2000 license.txt
-rw-r--r-- 1 nobody nobody 75739 oct 10 2000 release_notes.html
-rw-r--r-- 1 nobody nobody 31902 oct 10 2000 whatsnew.html
فایل نصب doc_install.bin است، اما نمیتوانید آن را بلافاصله اجرا کنید. اگر این کار را انجام دهید، نصب بدون هیچ دلیل واضحی ناموفق خواهد بود. برای مشاهده توضیحات دقیق مراحل نصب، فایل index.html را در یک مرورگر وب باز کنید. این نصاب به یک ماشین مجازی جاوا (JVM) نیاز دارد؛ به طور خاص، برنامهای به نام java که باید در دایرکتوری PATH روی سیستم شما قرار داشته باشد. لطفاً توجه داشته باشید که PATH یک متغیر یونیکس است که مقدار آن، در قالب rep1:rep2:...:repn، دایرکتوریهای repi را که باید برای یک فایل اجرایی جستجو شوند، مشخص میکند. در اینجا، نصاب درخواست میکند که برنامهای به نام java اجرا شود. ممکن است نسخههای مختلفی از این برنامه داشته باشید، بسته به تعداد ماشینهای مجازی جاوایی که اینجا و آنجا نصب کردهاید. به طور منطقی، ما از نسخهای که توسط JBuilder 4 ارائه شده است استفاده خواهیم کرد که در /opt/jbuilder4/jdk1.3/bin قرار دارد. برای تنظیم این دایرکتوری در متغیر PATH:
[echo $PATH]
/usr/local/sbin:/usr/sbin:/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
[export PATH=/opt/jbuilder4/jdk1.3/bin/:$PATH]
[echo $PATH]
/opt/jbuilder4/jdk1.3/bin/:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
اکنون میتوانیم نصب مستندات را آغاز کنیم:
این یک نصب گرافیکی است که اکنون انجام خواهد شد:

این بسیار شبیه نصب JBuilder Foundation است. بنابراین در اینجا وارد جزئیات نمیشویم. یک صفحه وجود دارد که نباید آن را از دست بدهید:

نصبکننده معمولاً بهطور خودکار تشخیص میدهد که JBuilder Foundation را کجا نصب کردهاید. بنابراین، تنظیمات پیشفرض را تغییر ندهید، مگر اینکه البته نادرست باشند.
پس از نصب مستندات، آمادهٔ آزمایش مجدد JBuilder هستیم. برنامه را همانطور که در بالا نشان داده شده اجرا کنید. پس از باز شدن JBuilder، منوی Help/Help Topic را انتخاب کنید. در پنل سمت چپ، روی پیوند Tutoriels کلیک کنید:

JBuilder همراه با مجموعهای از آموزشها ارائه میشود تا به شما در شروع برنامهنویسی جاوا کمک کند. در زیر، ما آموزش «ساخت یک برنامه» را که در بالا توضیح داده شد، دنبال کردهایم.

در JBuilder، File/New Project را انتخاب کنید. یک جادوگر شما را در سه صفحه راهنمایی خواهد کرد:

ما قصد داریم یک پنجره ساده با عنوان «سلام به همه» ایجاد کنیم. این پروژه را coucou نامگذاری خواهیم کرد. این مثال توسط root اجرا شد. سپس JBuilder پیشنهاد میکند که همه پروژهها را در یک پوشه به نام jbproject در داخل پوشه اتصال root گروهبندی کنید. پروژه coucou در دایرکتوری coucou (میدان نام دایرکتوری پروژه) از jbproject قرار داده خواهد شد. [suivant] را ایجاد کنید.

این صفحهٔ دوم مسیرهای مختلف پروژهٔ شما را خلاصه میکند. چیزی برای تغییر وجود ندارد. [suivant] را اجرا کنید.

صفحه سوم از شما میخواهد پروژه خود را سفارشیسازی کنید. جزئیات را پر کنید و [Terminer] را اجرا کنید.
اکنون Fichier/Nouveau را اجرا کنید:

Application را انتخاب کرده و روی OK کلیک کنید. یک جادوگر جدید دو صفحه نمایش خواهد داد:

میدان paquet حاوی نام پروژه است. میدان «Class» به مقدار nom نیاز دارد که به کلاس اصلی پروژه اختصاص داده میشود. نام بالا را بردارید و مقدار [suivant] را وارد کنید:

اپلیکیشن ما شامل یک کلاس جاوا دوم برای پنجرهٔ برنامه است. برای این کلاس یک نام انتخاب کنید. فیلد Titre عنوانی است که میخواهید به این پنجره بدهید. بخش options گزینههایی را برای پنجرهٔ شما ارائه میدهد. همگی را انتخاب کرده و [Terminer] را وارد کنید. سپس به محیط JBuilder بازمیگردید که اکنون با اطلاعاتی که برای پروژهتان ارائه کردهاید، بهروزرسانی شده است:

در پنجره سمت چپ بالا (۱)، فهرستی از فایلهای تشکیلدهنده پروژه خود را مشاهده خواهید کرد. اینها شامل دو کلاس .java است که ما همینالان نامگذاری کردهایم. در پنجره سمت راست (۲)، کد جاوا برای کلاس coucouCadre را مشاهده خواهید کرد. در پنجرهٔ پایین سمت چپ میتوانید ساختار (کلاسها، متدها، ویژگیها) پروژهٔ خود را مشاهده کنید. پروژه آمادهٔ اجرا است. روی دکمهٔ ۴ در بالا کلیک کنید، یا Run/Run Project را انتخاب کنید، یا F9 را انتخاب کنید. باید پنجرهٔ زیر را مشاهده کنید:

با کلیک بر روی گزینه Aide، اطلاعاتی را که به جادوگران ایجاد ارائه کردهاید، باید ببینید. ما بیشتر پیش نمیرویم. اکنون زمان آن است که به سراغ آموزشها برویم.
قبل از پایان، بیایید فقط نشان دهیم که شما میتوانید نه از JBuilder و رابط کاربری گرافیکی آن، بلکه از JDK که با خود آورده و در /opt/jbuilder4/jdk1.3 قرار داده است، استفاده کنید. فایل زیر را کامپایل کنید:
import java.io.*;
public class essai1{
public static void main(String args[]){
System.out.println("coucou");
System.exit(0);
}
}
بیایید آن را با استفاده از JDK JBuilder کامپایل و اجرا کنیم:






