*AM@NDA*
16th May 2010, 11:48 PM
بررسی ساختار فریم ها در جاوا
ساختار یك فریم در جاوا را می توان از دو دیدگاه مورد بررسی قرار داد. 1- دیدگاه ظاهر فریم 2- دیدگاه لایه بندی فریم
1- دیدگاه ظاهر فریم
یك فریم از لحاظ ظاهری از یكسری دكمه، عنوان فریم، آیكون فریم و حاشیه یا Border تشكیل شده است. این بعد از ساختار فریم ها نیاز به توضیح زیادی ندارد و در سایر مقالات به اندازه كافی به آن پرداخته شده است.
2- دیدگاه لایه بندی فریم
قبل از هرگونه توضیحی به دقت به شكل زیر توجه نمایید.
JFrame Layer
یك فریم در ظاهر دارای یك لایه می باشد ولی همانطور كه می بینیم این نظریه درست نبوده و یك فریم دارای چهار لایه اصلی زیر می باشد.
1- Root Pane 2- Layered Pane 3- Content Pane 4- Glass Pane
اولین نكته بسیار مهم، با توجه به مطالب بالا، آن است كه نمی توان مانند AWT به صورت مستقیم سایر كامپوننت های Swing را به JFrame اضافه نمود. در JFrame ها، معمولا كامپوننت های swing به Content Pane اضافه میشوند و بطور مستقیم به خود JFrame اضافه نمی شوند. در واقع یك فریم از چند قاب یا Pane مجزا تشكیل شده است و بهتر است كه در هنگام اضافه كردن سایر كامپوننت های دیگر به آن، مشخص كنیم كه قرار است كامپوننت مورد نظر به كدام قاب اضافه شود.
برای درك بهتر این قضیه كمی عمیق تر به این نكته می پردازیم. یك JFrame در واقع یك كانتینر سطح بالا یا top-level container می باشد. این نوع كامپوننت ها دارای یك نمونه از كامپوننت JRootPane می باشند. خود JRootPane شامل دو كامپوننت JPanel glassPane و JLayeredPane می باشد. اگر باز عمیق تر نگاه كنیم JLayeredPane از دو كامپوننت JMenuBar و JPanel contentPane تشكیل شده است.
jframe layers
پس به طور خلاصه و در یك جمله می توان گفت كه كامپوننت های Swing به صورت مستقیم به JFrame اضافه نمی شوند بلكه به یكی از قاب های آن اضافه می شوند. در ادامه به كمك دو برنامه نشان خواهیم داد كه چگونه می توان در قاب های مختلف یك فریم، كامپوننت های swing را اضافه نمود.
«برنامه شماره 1» اضافه كردن كامپوننت های swing به content pane
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TJFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
JLabel label = new JLabel("Add A JLable To contentPane", JLabel.CENTER);
frame.getContentPane().add(label);
frame.setSize(350, 200);
frame.setVisible(true);
{
{
«برنامه شماره 2» اضافه كردن كامپوننت های swing به glass pane
در این برنامه سه دكمه وجود دارد كه دوتای آنها به contentPane و سومی به glassPane اضافه شده است. همانطور كه در اولین شكل این مقاله می بینید، glassPane اولین لایه بوده و روی سایر لایه ها قرار دارد. اگر برنامه زیر را اجرا نمایید و به خروجی آن دقت كنید، خواهید دید كه دكمه ای كه به glassPaneاضافه شده ا ست روی دو دكمه دیگر قرار دارد و این امر نشان دهنده بحث لایه بندی در فریم ها می باشد.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainClass3 {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel p1 = new JPanel();
p1.add(new JLabel("GlassPane Example"));
JButton show = new JButton("Show");glassPane
p1.add(show);
p1.add(new JButton("No-op"));
f.getContentPane().add(p1);
final JPanel glass = (JPanel)f.getGlassPane();
glass.setVisible(true);
glass.setLayout(new GridBagLayout());
JButton glassButton = new JButton("Hide");
glass.add(glassButton);
f.setSize(180, 100);
f.setVisible(true);
show.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
glass.setVisible(true);
p1.repaint();
}
});
glassButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
glass.setVisible(false);
p1.repaint();
}
});
}
}
با توجه به مطالب قبل دریافتیم كه كلاس JLayeredPane بخش از JRootPane می باشد. در واقع این JLayeredPane فراتر از یك لایه بوده و كانتینری است كه نقش مدیریت مجموعهای از لایه ها و كامپوننت های موجود در آنها را بر عهده دارد. نحوه قرار گیری لایه ها در این بخش با توجه به اولویت آنها تعیین می شود. به عبارت دیگر هر لایه دارای یك شماره می باشد و در نتیجه هر لایه ای كه شماره آن كوچك تر باشد، بالاتر از سایر لایه ها قرار می گیرد.
در هنگام اضافه كردن كامپوننت ها به فریم، اگر بخواهیم تعیین كنیم كه هر كامپوننت در كدام لایه قرار گیرد، كافیست از متد زیر كه دارای دو آرگومان ورودی میباشد، استفاده نماییم.
JFrame f = new JFrame();
JLayeredPane lp = f.getLayeredPane();
lp.add(button, new Integer(1));
همانطور كه می بینید در تكه كد قبل یك دكمه به لایه شماره 1 افزوده شده است. برای درك بهتر، برنامه زیر را با دقت بررسی نمایید.
import javax.swing.*;
import java.awt.Color;
public class SimpleLayers {
public static void main(String[] args) {
// Create a frame & gets its layered pane
JFrame f = new JFrame();
JLayeredPane lp = f.getLayeredPane();
// Create 3 buttons
JButton top = new JButton("1");JLayeredPane
top.setBackground(Color.white);
top.setBounds(20, 20, 50, 50);
JButton middle = new JButton("2");
middle.setBackground(Color.red);
middle.setBounds(50, 50, 50, 50);
JButton bottom = new JButton("3");
bottom.setBackground(Color.yellow);
bottom.setBounds(78, 78, 50, 50);
// Place the buttons in different layers
lp.add(middle, new Integer(2));
lp.add(top, new Integer(3));
lp.add(bottom, new Integer(1));
// Show the frame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(160, 180);
f.setVisible(true);
}
}
در خروجی سه دكمه با رنگ های سفید، قرمز و زرد به ترتیب در سه لایه مختلف «لایه 1، لایه 2، لایه 3» قرار می گیرند. با اجرای برنامه متوجه خواهید شد كه سه دكمه روی یكدیگر قرار دارند. حال سعی كنید كه شماره لایه دو تا از دكمه ها را یكی كنید و نتیجه را با وضعیت فعلی مقایسه نمایید. دقت كنید كه حتما نیاز نیست شماره لایه ها از یك شروع شده و به ترتیب نیز باشند. بلكه می توانید از هر شماره دیگر دلخواه نیز شرو كرده و فقط باید شماره ها متفاوت باشند. مثلا می توانستیم به جای سه شماره فوق به ترتیب 10 ، 20 و 30 قرار دهیم.
كنترل دكمه Close یا ضربدر بالای فریم
نكته مهم دیگر كه در کدهای بالا نیز وجود دارد استفاده از متد ()setDefaultCloseOperation می باشد. استفاده از این متد سبب می شود تا زمانی كه كاربر بر روی دكمه close بالای فریم كلیك كند، فریم بسته می شود. این متد دارای چهار آرگومان ورودی می باشد كه عبارتند از : JDialog استفاده شوند) :
1- DO_NOTHING_ON_CLOSE
با ارسال این آرگومان به متد فوق، وقتی کاربر بر روی دکمه close كلیك كند، هیچ اتفاقی نمی افتد و فرم بسته نخواهد شد.
2- HIDE_ON_CLOSE
این آرگومان، مقدار پیش فرض متد فوق می باشد. با انتخاب این مقدار در واقع زمانی كه كاربر دكمه close را كلیك می كند، فریم بسته نمی شود بلكه مخفی می شود «Hide» و می توان در مراحل بعد دوبار آن فریم را به كمك متدهای دیگر نمایش داد.
3- DISPOSE_ON_CLOSE
این مقدار سبب بسته شدن فریم می شود. علاوه بر بستن فریم مورد نظر، تمامی منابع سیستم كه در اختیار فریم است نیز آزاد شده و به سیستم باز گردانده می شوند.
4- EXIT_ON_CLOSE
با ارسال این آرگومان به متد، برنامه خاتمه می یابد. این آرگومان معادل دستور زیر عمل می كند.
system.exit(0);
ساختار یك فریم در جاوا را می توان از دو دیدگاه مورد بررسی قرار داد. 1- دیدگاه ظاهر فریم 2- دیدگاه لایه بندی فریم
1- دیدگاه ظاهر فریم
یك فریم از لحاظ ظاهری از یكسری دكمه، عنوان فریم، آیكون فریم و حاشیه یا Border تشكیل شده است. این بعد از ساختار فریم ها نیاز به توضیح زیادی ندارد و در سایر مقالات به اندازه كافی به آن پرداخته شده است.
2- دیدگاه لایه بندی فریم
قبل از هرگونه توضیحی به دقت به شكل زیر توجه نمایید.
JFrame Layer
یك فریم در ظاهر دارای یك لایه می باشد ولی همانطور كه می بینیم این نظریه درست نبوده و یك فریم دارای چهار لایه اصلی زیر می باشد.
1- Root Pane 2- Layered Pane 3- Content Pane 4- Glass Pane
اولین نكته بسیار مهم، با توجه به مطالب بالا، آن است كه نمی توان مانند AWT به صورت مستقیم سایر كامپوننت های Swing را به JFrame اضافه نمود. در JFrame ها، معمولا كامپوننت های swing به Content Pane اضافه میشوند و بطور مستقیم به خود JFrame اضافه نمی شوند. در واقع یك فریم از چند قاب یا Pane مجزا تشكیل شده است و بهتر است كه در هنگام اضافه كردن سایر كامپوننت های دیگر به آن، مشخص كنیم كه قرار است كامپوننت مورد نظر به كدام قاب اضافه شود.
برای درك بهتر این قضیه كمی عمیق تر به این نكته می پردازیم. یك JFrame در واقع یك كانتینر سطح بالا یا top-level container می باشد. این نوع كامپوننت ها دارای یك نمونه از كامپوننت JRootPane می باشند. خود JRootPane شامل دو كامپوننت JPanel glassPane و JLayeredPane می باشد. اگر باز عمیق تر نگاه كنیم JLayeredPane از دو كامپوننت JMenuBar و JPanel contentPane تشكیل شده است.
jframe layers
پس به طور خلاصه و در یك جمله می توان گفت كه كامپوننت های Swing به صورت مستقیم به JFrame اضافه نمی شوند بلكه به یكی از قاب های آن اضافه می شوند. در ادامه به كمك دو برنامه نشان خواهیم داد كه چگونه می توان در قاب های مختلف یك فریم، كامپوننت های swing را اضافه نمود.
«برنامه شماره 1» اضافه كردن كامپوننت های swing به content pane
import javax.swing.JFrame;
import javax.swing.JLabel;
public class TJFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("Swing Frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
JLabel label = new JLabel("Add A JLable To contentPane", JLabel.CENTER);
frame.getContentPane().add(label);
frame.setSize(350, 200);
frame.setVisible(true);
{
{
«برنامه شماره 2» اضافه كردن كامپوننت های swing به glass pane
در این برنامه سه دكمه وجود دارد كه دوتای آنها به contentPane و سومی به glassPane اضافه شده است. همانطور كه در اولین شكل این مقاله می بینید، glassPane اولین لایه بوده و روی سایر لایه ها قرار دارد. اگر برنامه زیر را اجرا نمایید و به خروجی آن دقت كنید، خواهید دید كه دكمه ای كه به glassPaneاضافه شده ا ست روی دو دكمه دیگر قرار دارد و این امر نشان دهنده بحث لایه بندی در فریم ها می باشد.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MainClass3 {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JPanel p1 = new JPanel();
p1.add(new JLabel("GlassPane Example"));
JButton show = new JButton("Show");glassPane
p1.add(show);
p1.add(new JButton("No-op"));
f.getContentPane().add(p1);
final JPanel glass = (JPanel)f.getGlassPane();
glass.setVisible(true);
glass.setLayout(new GridBagLayout());
JButton glassButton = new JButton("Hide");
glass.add(glassButton);
f.setSize(180, 100);
f.setVisible(true);
show.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
glass.setVisible(true);
p1.repaint();
}
});
glassButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
glass.setVisible(false);
p1.repaint();
}
});
}
}
با توجه به مطالب قبل دریافتیم كه كلاس JLayeredPane بخش از JRootPane می باشد. در واقع این JLayeredPane فراتر از یك لایه بوده و كانتینری است كه نقش مدیریت مجموعهای از لایه ها و كامپوننت های موجود در آنها را بر عهده دارد. نحوه قرار گیری لایه ها در این بخش با توجه به اولویت آنها تعیین می شود. به عبارت دیگر هر لایه دارای یك شماره می باشد و در نتیجه هر لایه ای كه شماره آن كوچك تر باشد، بالاتر از سایر لایه ها قرار می گیرد.
در هنگام اضافه كردن كامپوننت ها به فریم، اگر بخواهیم تعیین كنیم كه هر كامپوننت در كدام لایه قرار گیرد، كافیست از متد زیر كه دارای دو آرگومان ورودی میباشد، استفاده نماییم.
JFrame f = new JFrame();
JLayeredPane lp = f.getLayeredPane();
lp.add(button, new Integer(1));
همانطور كه می بینید در تكه كد قبل یك دكمه به لایه شماره 1 افزوده شده است. برای درك بهتر، برنامه زیر را با دقت بررسی نمایید.
import javax.swing.*;
import java.awt.Color;
public class SimpleLayers {
public static void main(String[] args) {
// Create a frame & gets its layered pane
JFrame f = new JFrame();
JLayeredPane lp = f.getLayeredPane();
// Create 3 buttons
JButton top = new JButton("1");JLayeredPane
top.setBackground(Color.white);
top.setBounds(20, 20, 50, 50);
JButton middle = new JButton("2");
middle.setBackground(Color.red);
middle.setBounds(50, 50, 50, 50);
JButton bottom = new JButton("3");
bottom.setBackground(Color.yellow);
bottom.setBounds(78, 78, 50, 50);
// Place the buttons in different layers
lp.add(middle, new Integer(2));
lp.add(top, new Integer(3));
lp.add(bottom, new Integer(1));
// Show the frame
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(160, 180);
f.setVisible(true);
}
}
در خروجی سه دكمه با رنگ های سفید، قرمز و زرد به ترتیب در سه لایه مختلف «لایه 1، لایه 2، لایه 3» قرار می گیرند. با اجرای برنامه متوجه خواهید شد كه سه دكمه روی یكدیگر قرار دارند. حال سعی كنید كه شماره لایه دو تا از دكمه ها را یكی كنید و نتیجه را با وضعیت فعلی مقایسه نمایید. دقت كنید كه حتما نیاز نیست شماره لایه ها از یك شروع شده و به ترتیب نیز باشند. بلكه می توانید از هر شماره دیگر دلخواه نیز شرو كرده و فقط باید شماره ها متفاوت باشند. مثلا می توانستیم به جای سه شماره فوق به ترتیب 10 ، 20 و 30 قرار دهیم.
كنترل دكمه Close یا ضربدر بالای فریم
نكته مهم دیگر كه در کدهای بالا نیز وجود دارد استفاده از متد ()setDefaultCloseOperation می باشد. استفاده از این متد سبب می شود تا زمانی كه كاربر بر روی دكمه close بالای فریم كلیك كند، فریم بسته می شود. این متد دارای چهار آرگومان ورودی می باشد كه عبارتند از : JDialog استفاده شوند) :
1- DO_NOTHING_ON_CLOSE
با ارسال این آرگومان به متد فوق، وقتی کاربر بر روی دکمه close كلیك كند، هیچ اتفاقی نمی افتد و فرم بسته نخواهد شد.
2- HIDE_ON_CLOSE
این آرگومان، مقدار پیش فرض متد فوق می باشد. با انتخاب این مقدار در واقع زمانی كه كاربر دكمه close را كلیك می كند، فریم بسته نمی شود بلكه مخفی می شود «Hide» و می توان در مراحل بعد دوبار آن فریم را به كمك متدهای دیگر نمایش داد.
3- DISPOSE_ON_CLOSE
این مقدار سبب بسته شدن فریم می شود. علاوه بر بستن فریم مورد نظر، تمامی منابع سیستم كه در اختیار فریم است نیز آزاد شده و به سیستم باز گردانده می شوند.
4- EXIT_ON_CLOSE
با ارسال این آرگومان به متد، برنامه خاتمه می یابد. این آرگومان معادل دستور زیر عمل می كند.
system.exit(0);