استفاده از JTable در جاوا – قسمت دوم
استفاده از JTable در جاوا- قسمت دوم
در قسمت قبل نحوه ایجاد JTable در جاوا با استفاده از معرفی نام ستون ها و اطلاعات جدول را گفتم.برای دیدن قسمت قبل به لینک زیر مراجعه کنید:
استفاده از JTable درجاوا- قسمت اول
در این آموزش قصد دارم نحوه ایجاد جدول با استفاده از یک Table Model را شرح دهم.
همانطور که در قسمت قبلی شرح داده شد،به دو صورت می توان اطلاعات یک جدول را به JTable معرفی کرد. روش اول که استفاده آرایه ها بود توضیح داده شد. روش بعدی استفاده از Table Model است. در این روش باید کلاسی ایجاد کنیم که از کلاس AbstractTableModel ارث بری کند. و یک Object از این کلاس را به عنوان آرگمان ورودی به متد سازنده JTable دهیم.
کلاس AbstractTableModel یک کلاس Abstract است که دارای ۳ متد Abstract است که باید توسط ما پیاده سازی شود. این متد ها عبارتند از:
- public int getRowCount()
- public int getColumnCount()
- public Object getValueAt(int rowIndex, int columnIndex)
برای ایجاد TableModel پیاده سازی این ۳ متد الزامی است. در این روش هم باید یک آرایه برای نام ستون ها و یک آرایه دو بعدی برای اطلاعات جدول تعریف کنیم و در سه متد گفته شده از آنها استفاده کنیم. پس کدهای برنامه تا اینجا شیبه کد زیر است:
Public class TableModel extends AbstractTableModel { private String[] col = new String[]{ "col-0", "col-1", "col-2", "col-3" }; // private String[][] data = new String[][]{ {"val-00", "val-01", "val-02", "val-03"}, {"val-10", "val-11", "val-12", "val-13"}, {"val-20", "val-21", "val-22", "val-23"}, {"val-30", "val-31", "val-32", "val-33"} }; @Override public int getRowCount() { } @Override public int getColumnCount() { } @Override public Object getValueAt(int rowIndex, int columnIndex) { } }
حال وقت آن است که بدنه ی متد ها را پیاده سازی کنیم.
متد getRowCount تعداد سطر های جدول را بر می گرداند، پس باید از تعداد سطر های آرایه data استفاده کنیم. به شکل زیر:
@Override public int getRowCount() { return data.length; }
متد getColumnCount تعداد ستون های جدول را بر می گرداند، پسمی توانیم از طول آرایه col استفاده کنیم. به این شکل:
@Override public int getColumnCount() { return col.length; }
متد دیگری به نام getColumnName وجود دارد که برای شاناساندن نام ستون ها به JTable استفاده می شود. وجود این متد الزامی نیست ولی اگر آن را پیاده سازی نکنیم نام ستون ها یا حروف a تا Z یا ترکیبی از آنها مشخص می شود. این یعنی اگر بخواهیم که نام ستون ها را خودمان تعیین کنیم باید این متد را که در کلاس AbstractTableModel قرار دارد Override کنیم.
شکل کلی این متد به این صورت است:
public String getColumnName(int column)
برای پیاده سازی آن باید نام ستون خواسته شده را برگردانیم. به شکل زیر:
@Override public String getColumnName(int column) { return col[column]; }
متد getValueAt آدرس یک سلول از جدول را می گیرد و اطلاعات آن سلول را به صورت یک Object بر می گرداند. این Object میتواند هر نوعی باشد. این Object حتی میتواند از نوع کامپوننت ها باشد. اطلاعات ما در این مثال فقط از نوع String است. پس این متد را میتوانیم اینگونه پیاده سازی کینم:
@Override public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; }
تا اینجا کارهایی که برای ساخت کلاس TableModel الزامی بود را انجام دادیم. البته میتوانیم متد های دیگری را هم که در کلاس AbstractTableModel وجود دارند را بسته به نیازمان Override کنیم. مثلا متد setValueAt یا متد getColumnClass یا متد isCellEditable که قصد دارم آموزش این متد ها را در یک قسمت به صورت جداگانه قرار دهم.
حال برای اینکه بتوانیم از کلاس TableModel استفاده کنیم باید یک JTable ایجاد کنیم و یک Object از نوع کلاس TableModel را به سازنده ی سازنده ی JTable پاس دهیم. به صورت زیر:
TableModel tableModel = new TableModel(); JTable table = new JTable(tableModel);
و در ادامه باید باید table را به Jframe اضافه کنیم(add کنیم) و JFrame را نمایش دهیم. که این کار در قسمت قبل توضیح داده شد.
کد کامل برنامه در زیر آورده شده است:
کلاس TableModel
import javax.swing.table.AbstractTableModel; public class TableModel extends AbstractTableModel { private String[] col = new String[]{"col-0", "col-1", "col-2", "col-3"}; private String[][] data = new String[][]{{"val-00", "val-01", "val-02", "val-03"}, {"val-10", "val-11", "val-12", "val-13"}, {"val-20", "val-21", "val-22", "val-23"}, {"val-30", "val-31", "val-32", "val-33"}}; @Override public int getRowCount() { return data.length; } @Override public int getColumnCount() { return col.length; } @Override public Object getValueAt(int rowIndex, int columnIndex) { return data[rowIndex][columnIndex]; } @Override public String getColumnName(int column) { return col[column]; } }
کلاس TableModelDemo برای استفاده از TableModel
import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; public class TableModelDemo extends JFrame { private JTable table; private TableModel tableModel; public TableModelDemo() { super("Table Model Demo"); setSize(470, 470); setLayout(new FlowLayout()); setDefaultCloseOperation(EXIT_ON_CLOSE); TableModel tableModel = new TableModel(); JTable table = new JTable(tableModel); JScrollPane scrollPane = new JScrollPane(table); add(scrollPane); } public static void main(String args[]) { TableModelDemo tableModelDemo = new TableModelDemo(); tableModelDemo.setVisible(true); } }
این برنامه دقیقا شبیه به برنامه ی قسمت قبل آموزش استفاده از JTable بود با این تفاوت که از یک TableModel برای مشخص کردن اطلاعات جدول استفاده شده بود. به امید خدا در قسمت بعدی آموزش به بررسی متد های دیگر کلاس AbstractTableModel و امکانات دیگر آن و نحوه اضافه کردن ، حذف کردن و آپدیت کردن یک سطر از جدول در زمان اجرای برنامه خواهم پرداخت.
لطفا نظرات و انتقادات خود را در مورد کیفیت آموزش ها بیان بفرمایید تا در قسمت های بعد آموزش، از آنها در بهتر کردن کیفیت آموزش ها استفاده کنم.
همچنین اگر موضوع خاصی برای آموزش های بعدی (بعد از اتمام مبحث JTable) در نظر دارید در قسمت نظرات بیان بفرمایید تا بعد از اتمام مبحث JTable به آموزش آن مبحث بپردازم. موفق و سربلند باشید
با سلام
آقا امید، واقعا خیلی عالی بودن، ما که خیلی لذت بردیم.
چرا ادامه نمیدین آخه؟
ما منتظریما.
راستی، من یه مشکلی داشتم با این جدول که خیلی جدیه، تو سایت برنامه نویس پستش کردم، بخش نگارش استاندارد جاوا
موضوع: حذف سطر جدولی که سطر و ستون آن از طریق فایل متنی معین میشود..
ببین راه حلی براش داری؟
دعات میکنم
یاحق
خواهش میکنم
راستش سرم فوق العاده شلوغه، و خب استقبال دوستان زیاد نیست که اصرار زیادی برای ادامه آموزش ها به صورت منظم داشته باشم.
ولی حتما در نظر دارم که از یک ماه دیگه که سرم خلوت شد ، انواع مطالب آموزشی به صورت سریالی آماده کنم و روی سایت قرار بدم. امیدوارم استقبال بشه یا دوستان حداقل نظرشونودر مورد اموزش ها بگن.
واسه مشکلتم سعی میکنم هر چه سریع تر راهنماییت کنم
موفق باشی
سلام
ممنون خیلی عالی بود
ادامه بدید
سلام حامد جان. خواهش میکنم
حتما به زودی سایت پرباری خواهید دید
بهتون تبریک میگم منتظر پرو/زه های اموزشی بعدی شما هستیم
ممنونم.
دو تا آموزش دیگه تقریبا آمادس که امروز یا فردا روی سایت قرارش میدم
سلام جناب سریعتر بزارید پس فردا امتحان جاوا دارم با تشکر
سلام دوست عزیز
آموزش ها رو قرار دادم.
فیلم های آموزشی ، بخش پنجم و ششم رو مشاهده بفرمایید.
یه آموزش دیگه هم داره آماده میشه که پروژه کامل ایجاد یه ماشین حساب گرافیکی هست. به محض آماده شدن روی سایت قرارش خواهد گرفت
تشکر.
سلام،ممنون از مطالب خوب و مفیدتون….
من تازه کار با جاوا رو شروع کردم، یه سوال در مورد jtable دارم که ممنون میشم راهنمایی کنید.
من یه پروژه دارم که توی اون چندتا jtable دارم و میخوام که جدولها اطلاعتشونو از دیتابیس بگیرن، الان به نظر شما من توی این برنامه باید یک کلاس tablemodel داشته باشم؟؟ و برای هرکدوم از جدولها یه تابع توی این کلاس بذارم که data و col رو از دیتابیس پر کنه؟؟ نمیدونم باید چه جور بپرسم، متوجه منظورم شدین؟؟
سلام.خواهش میکنم.
بله باید TableModel داشته باشید. ولی تابع خاصی نمیخواد. میتونید توی کانسترکتور TableModel نام جدول در دیتابیس رو بگیرید و اطلاعات همون جدول رو نمایش بدید.
کد نگاشت جدول دیتابیس به JTable رو بدون استفاده از TableModel در این لینک نوشتم:
نگاشت جدول دیتابیس در یک JTable
شما اگه از TableModel استفاده میکنی کافیه به جز خط آخر کد، همه ی کد ها رو توی کانسترکتور کپی کنی.بقیه TableModel هم طبق آموزش بنویس.
اگه سوالی بود بفرمایید.
موفق باشی
واقعا ممنون……
من قبلا به همون روشی که شما گفتین با jtable کار کرده بودم ولی با tablemodel نه، یه جایی دیدم که اگه بخوام همزمان با حذف و اضافه کردن به دیتابیسم جدولم هم بروز بشه باید از tablemodel استفاده کنم، درسته؟؟ اگه بدون tablemodel هم میشه اینکارو کرد،میشه بگید چطور؟؟
حالا من این کاری که شما گفتینو کردم،البته هنوز جواب نگرفتم!! تو قسمت private من اینا رو اضافه کردم:
private ResultSet rs;
private Connection c;
private Statement st;
Vector data = new Vector();
Vector columnNames = new Vector();
یعنی data, columnnames رو اوردم تو قسمت private، بقیه کد رو هم که تو قسمت کانسترکتور کپی کردم، تا اینجا که مشکلی نداره؟؟
نه مشکلی نداره.
ببینید.بهترین راه برای مدیریت JTable استفاده از Model هست. که کدهاتونو لایه بندی میکنه.
اون کدی که من نوشتمش یه قطعه کده که هر جایی میشه ازش استفاده کرد. چه توی TableMode چه بیرون TableModel.
همونطور که گفتم، همه چیز دقیقا مثل آموزشه. فقط در کانسترکتور TableModel باید از کدی که توی اون سایت نوشته بودم استفاده کنید.
ببخشید که من زیاد سوال میپرسم، حالا من تو پروژه م مثلا ۳ تا جدول دارم که هر کدوم اطلاعات یکی از جدولای دیتابیسم رو نمایش میده، یکی اطلاعات دانش اموز، یکی اطلاعات پرسنلی و…. حالا برای هرکدوم از این جدولا باید یه tablemodel بسازم؟؟ یه tablemodel برای نمایش دانش اموزها و یه tablemodel برای پرسنل؟؟
خواهش میکنم.
شما میتونی یه TableModel که تمام کارهای مشترک همه TableModel ها رو داره رو ایجاد کنی، بعد برای هر کدوم از JTable ها یه TableModel بنویسی که از TableModelی که از این TableModelی که امکانات مشترک رو در خودش داشت ارث بری کنه.
واقعا ممنون، دستتون درد نکنه…… دمتون گرم……
با tablemodel هم جواب گرفتم، فقط همین سوال اخری که پرسیدمو لطف کنید جواب بدین واقعا ممنون میشم، یعنی برای هرکدوم از جدولا یه tablemodel ؟؟؟؟؟؟
خدا رو شکر 🙂
خیلی ممنون….
میشه یه آموزش کامل در مورد jtable قرار بدین؟؟ یه سری مسایل مثل کلیک روی جدول، درج و حذف توی جدول و ….
خواهش میکنم.
در بخش آموزش دفترچه تلفن آموزش نسبتا کاملی قرار داده شد. ولی سعس میکنم در آیده یه آموزش تکمیلی هم قرار یدم.
سلام، آقای فرجی یه سوال توی این تاپیک در مورد کلیک روی جدول پرسیدم، خیلی ممنون میشم اگه شما هم یه نگاه بندازین و اگه ممکنه جواب بدین، خیلی تو این قضیه گیر کردم
http://barnamenevis.org/showthread.php?414393-%D8%B1%D9%88%DB%8C%D8%AF%D8%A7%D8%AF-click-%D8%B1%D9%88%DB%8C-jtable
لینکو ندیدین مهندس؟؟؟؟؟؟ خواهش میکنم حداقل شما جواب بدین بدجور کلافه م کرده نمیفهمم چشه
سلام،فک میکنم اینجا بپرسم زودتر جواب میدین:
ببینید من یه جدول به همون روش tablemodel ایجاد کردم همونطور که خودتون گفتین، حالا جدولمو روی یه panel قرار دادم
وقتی این کد رو مینویسم جدول میاد ولی کلیک روی جدول اجرا نمیشه:
وقتی این دو خط رو جابه جا میکنم یه panel خالی میاد که وقتی روی اون کلیک میکنم رویداد کلیک جدولم اجرا میشه، چرا؟؟؟؟؟؟؟
منظورم دو خط آخره که جابه جا میکنم
سلام. جوابتونو همونجا دادم. لطفا از همونجا پیگیر بقیه ی مشکلات اون تاپیک باشید. ممنون 🙂
ممنون از اینکه جوابمو دادین، گفتم شاید اینجا بیشتر میاین، چشم.
سلام، ببخشید که من دوباره مزاحم میشم، یه سوال دیگه در مورد jtable دارم:
چطور میتونم با زدن یه button، یه کلیک رو جدول یا …. یه رویدادی ، اطلاعات جدولمو تغییر بدم، درواقع من میخوام یه جدول داشته باشم که اطلاعات افرادم رو نشون بده بعد با کلیک روی این جدول و دریافت id اون شخص، روی یه جدول دیگه اطلاعات چک هایی که اون طرف صادر کرده رو نشون بده، برای نفر اول اینکارو انجام میدم اما وقتی میخوام چکهای نفر دوم رو نشون بده جدول تغیر نمیکنه، میشه در این مورد هم راهنمایی کنید؟؟
سلام. خواهش میکنم دوست عزیز.
اگه میخوای اصولی کار کنی، باید در TableModel هر JTable متغییر data یا همون اطلاعات جدول رو به صورت Generic تعریف کنی. مثلا یه Vector که نوع داخلش آبجکت هایی از کلاس Person هستند. با این کار اطلاعات هر سطر از JTable داخل یه bean یا یه آبجکت از نوع Person نگهداری میشه و دستتون خیلی بازتر میشه.
مثلا میتونی آبجکت Personی که در سطر انتخاب شده هست رو به دست بیاری و بدی به یه کلاس تا جدول مربوط به چک ها و غیره رو بر اساس این آبجکت نمایش بده.
نکتش اینه که هر دفعه باید اطلاعات مربوط به چک ها رو ایجاد کنی و جایگزین اطلاعات قبلی TableModel کنی و با استفاده از متد fireTableDataChanged اطلاعات JTable رو refresh کنی.
استفاده از Generic معجزه میکنه 🙂
قسمت اولشو متوجه شدم ولی از اونجا که گفتین “باید هر دفعه اطلاعات مربوط به چک ها رو ایجاد کنی” به بعدشو نفهمیدم!!
من این کد رو نوشتم:
کانسترکتور کلاس TableModel_chek یه آرگومان ورودی داره که در واقع ID اون شخصه که با کلیک روی جدول افراد به دست اومده، که این id رو به این کلاس میفرسم و اطلاعات چک رو برمیگردونه و میخوام با هر بار کلیک روی هر کدوم از سطرهای جدول افراد، جدول چک refresh بشه، ولی این اتفاق نمیفته!! firetable رو درست گذاشتم؟؟
تا الان فهمیدم که tablemodel مقاددیر جدید رو میگیره ولی این تغییرات روی table اعمال نمیشه!!
کارت اشتباهه.
اگه دوست داشتی کل پروژه رو برام بفرست و یه توضیحات تکمیلی هم بده تا من برات درستش کنم.
اینجوری به جایی نمیرسیم.
میشه بگید کجاش اشتباهه؟؟ بهتر نیس خودم تمومش کنم؟؟
کلا روشت اشتباهه. اگه بخوام اینجوری توضیح بدم که چیکار کنی، باید کل پروژه رو از اول تا آخر توضیح بدم.
در ضمن، Java Naming و Encapsulation رو هم اصلا رعایت نکردی. در جاوا نامگذاریه متغییر ها با PHP و دیگر زبان ها متفاوته.
من حدس میزنم شما هنوز یه کمی با OOP مشکل داری.
خب درسته! من تازه کار با جاوا رو شروع کردم و این اولین برنامه ایه که با جاوا مینویسم…
پس میشه یه راهنمایی کنید که چطوری جاوا رو درست و اصولی یاد بگیرم؟؟؟
راستی نظرتون راجع به Jdeveloper چیه؟؟
بهترین کار همین کاریه که شما داری انجام میدی. باید تا میتونی پروژه برای خودت تعریف کنی و بنویسی. و هر جا به مشکل برخوردی به کتاب های مرجع مراجعه کنی. و اگه در کتاب مرجع جواب نگرفتی ، در Forum ها برنامه نویسی سوالتو مطرح کنی. در ضمن میتونی پروژه های Open Source رو هم ببینی که چطور اصول رو رعایت کردن ، و تو هم همونطوری عمل کنی.
البته قبل از همه ی این کارا مطالعه یه سری مقدمات و مطالب در مورد اصول شی گرایی و کلا کد نویسی ضروریه و بهترین منبع برای این مطالعات کتاب های مرجع هست.
در مورد JDeveloper هم باید بگم شما که هنوز اول کاری بهتره با Netbeans کار کنی بعدا IDE های دیگه رو هم امتحان کنی.
موفق باشی
ممنون از راهنماییتون….. سایتتون عالیه و خودتون هم عالی هستین که جواب آدمای بیسوادی مثل منو میدین…..
بازم ممنون……
ممنونم. کمک کردن وظیفه ی همس. شما هم بیسواد نیستی 😉
حالا یه سوال اصولی دیگه، من توی دیتابیسم مثلا سه تا جدول دارم به اسم دانش آموز، ثبت نام و گروه آزمایشی، حالا توی پروژه برای هر کدوم از این موجودیت ها یه کلاس ایجاد کردم که توابع set , get رو توی اونها نوشتم، یه کلاسم برای اتصال به دیتابیس نوشتم، حالا به نظر شما برای توابع insert , update,delet, select که مربوط به دیتابیسه برای هرکدوم یه کلاس ایجاد کنم یا این توابع رو توی همون کلاس هایی که برای موجودیت هام ایجاد کردم بنویسم؟؟
هیچ کدوم.
به نظر من بهترین راه اینه که یه کلاس داشته باشی(مثلا به اسم DB) که چند تا متد static داشته باشه(مثلا insert ، update ، delete و …) و این متد ها فقط کارشون اینه که یه Query بگیرن و همه ی کارای اتصال به Database و انجام Query و بستن کانکشن رو انجام بدن. و برای هر Entity هم یه کلاس تعریف کنی (مثلا به اسم StudentDBHelper) و این کلاس ها هم همه هر کدوم متد های insert ، update ، delete و … رو دارند با این تفاوت که این متد ها یه Object از Entityی مورد مورد نظر میگیرن و Query رو میسازن و میدن به متدهای static کلاس DB.
یه مثال:
حالا هر جا خواستی یه Student به Database اضافه کنی، کافیه یه Object از کلاس StudentDBHelper ایجاد کنی و به متد indertش یه آبجکت Student بدی تا برای توی دیتابیس بریزتش.
به این نوع برنامه نویسی برنامه نویسی چند لایه میگن . البته نحوه پیاده سازی لایه ها، بسته به منطق برنامه ی شما میتونه متفاوت باشه.
سلام ممنون از مطالب مفیدتون کار من رو ساده کرد و از نکاتتون خیلی استفاده کردم سپاسگزارم
خواهش میکنم. باعث افتخاره. موفق باشید