مترجم: حبيب الله عليخاني
منبع: راسخون
منبع: راسخون
نمایش اطلاعات
برای نمایش اطلاعات نیاز به شی ای بنام jTable داریم. به همین منظور ابتدا در مورد این شی چند نکته را مطرح می کنیم.عنصر Table از کلاس JTable است. کلاس JTable به صورت شکل زیر از کلاسهای دیگر ارث بری کرده است:
در پروژه ای که داریم کلاس JFrame ای به نام AreayTOjtable ایجاد کرده ایم :
نیاز داریم. آرایه یک بعدی هدر ثابت و مشخص می باشد، اما برای آرایه ی دو بعدی دو حالت داریم:
حالت اول: نمایش اطلاعات یک آرایه ی ثابت(استاتیک) از پیش تعریف شده در شی jTable
حالت دوم: نمایش اطلاعات بانک اطلاعاتی در شی jTable
حالت اول: نمایش اطلاعات یک آرایه ی ثابت(استاتیک) از پیش تعریف شده در شی jTable
ابتدا جدولی که می خواهیم اطلاعات در آن نمایش داده شود را ایجاد می کنیم. این جدول شامل نام(sname) نام خانوادگی(sfamily) شهر(scity) سال تولد(birthyear) شماره تلفن(tell) می باشد.
جدول(jtable) زیر به همراه دکمه ی Show را در نظر بگیرید:
با دوبار کلیک روی دکمه ی Show دربخش design وارد متد ShowActionPerformed می شویم. در مورد متد ActionPerformed در بخش event توضیح داده شد.
در این متد، یک آرایه یک بعدی برای هدر(ستون) و یک آرایه دو بعدی برای سطرهای آن تعریف می کنیم. آرایه یک بعدی فهرستی از متغیرهای یکنوع می باشد و باید یک متغیر آرایه از نوع مورد نظر ایجاد کنید . فرم عمومی اعلان یک آرایه یک بعدی به شکل زیر است :
[]; نام متغییر نوع
نام متغییر نوع، تعیین کننده نوع داده برای هر یک از اعضا داخل آرایه است. در جاوا آرایه های چند بعدی در واقع آرایه ای از آرایه ها هستند. برای اعلان یک متغیر آرایه چند بعدی ، با استفاده از مجموعه دیگری از کروشه ها را مشخص می کنید.
فرم عمومی اعلان یک آرایه دو بعدی به شکل زیر است :
[][]; نام متغییر نوع
تعریف این دو آرایه و مقدار دهی آن در متد ShowActionPerformed به صورت زیر می باشد:
private void ShowActionPerformed (java.awt.event.ActionEvent evt) {
String[] column = {"sname","sfamily","scity","bithyear","tell"};
Object[][] row = {
{"habibollah","alikhani","esfahan",1366,"09394805740"},
{"fateme","raesiyan","sari",1367,"09306381530"},
{"rasekhoon","rasekhoon","esfahan",1300,"03116615580"},
};
}
آرایه column را که هدر جدول است، از نوع string تعریف می کنیم و آرایه ی row برای داده های داخل جدول، که اطلاعات افراد در آن است را از نوع آبجکت تعربف می کنیم تا بتوانیم هم نوع رشته در آن داشته باشیم و هم نوع عدد(برای سال تولد). نوع آبجکت هر مقداری را می توان بگیرد.String[] column = {"sname","sfamily","scity","bithyear","tell"};
Object[][] row = {
{"habibollah","alikhani","esfahan",1366,"09394805740"},
{"fateme","raesiyan","sari",1367,"09306381530"},
{"rasekhoon","rasekhoon","esfahan",1300,"03116615580"},
};
}
شی JTable یک سازنده دارد که در آن از ما یک آرایه دو بعدی و یک بعدی می گیرد که مقدار دهی اولیه می کند:
jTable1 = new JTable(row, column);
وقتیکه در زمان اجرا دکمه ی Show را می زنیم، اطلاعات آرایه را نشان نمی دهد و علت آن این است که در لحظه ی اجرا jScrollPane1 گرافیک JTable را می گیرد و زمانیکه JTable تغییر می کند، jScrollPane1 تغییر نکرد. برای این کار کد زیر را وارد می کنیم (view آنرا دوباره آپدیت می کنیم):
jScrollPane1.setViewportView(jTable1);
در ابتدا خروجی آن به صورت زیر می باشد:حالت دوم: نمایش اطلاعات بانک اطلاعاتی در شی jTable
در این مرحله، می خواهیم داده ها را از جدولی(student) از یک بانک اطلاعاتی وارد آرایه کنیم و سپس طی یک الگوریتم برنامه نویسی مقادیر این آرایه را در جدول نمایش دهیم، در واقع با این کار می خواهیم داده های بانک را در جدول نمایش دهیم(با واسطه ی آرایه).نام جدول بانک که در این مثال و مثال بعدی استفاده می شود، student می باشد که آنرا با استفاده از نرم افزار MYSQL Administrator ایجاد کرده ایم .
کدهای در این مثال را در btnShowActionPerformed می نویسیم تا با فشردن دکمه ی نمایش اطلاعات جدول را نشان دهد و چون می خواهیم به بانک وصل شویم، کدهای مربوط به connection را در این متد می نویسیم و از تکرار توضیح در مورد آن می پرهیزیم. (همه ی کدها را درون بلوک try می نویسیم):
private void btnShowActionPerformed (java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
st.close();
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
چون در این حالت مانند قبل از JTable استفاده می کنیم، به یک آرایه ی یک بعدی(استاتیک) برای هدر JTable نیاز داریم:try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
st.close();
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
برای همین در بخش کد، اعضای آرایه ی یک بعدی Header را هم فارسی تایپ کردیم:
String[] Header = {"تلفن","سال تولد"," شهر", "نام خانوادگی", "نام",""کد ملی };
بجای آرایه ی زیر:
String[] Header = {"sname","sfamily","scity","bithyear","tell"};
و همچنین یک آرایه ی دو بعدی(دینامیک) برای مقادیر درون JTable و بانک نیاز داریم.در مثال قبل یک آرایه ی دوبعدی از پیش تعریف شده داشتیم که مقدار اولیه ی ثابت داشت. اما اکنون می خواهیم یک آرایه ی دوبعدی دینامیک را New کنیم که مقدار ثابت ندارد و مقادیر متغییر بانک در آن ریخته می شود. برای New کردن یک آرایه باید سایز ابعاد آن را داشته باشیم یعنی باید بدانیم که چند در چند است. برای جدول مورد نظر در مثال بالا تعداد ستونcc (column count) برابر 6 می باشد و ثابت است . ولی تعداد سطر های آن متغییر است و به بانک بستگی دارد. برای بدست آوردن تعداد سطر، ابتدا مکان نما را از طریق متد Last() به انتهایrs که متغییر resultset می باشد می فرستیم و سپس شماره ی سطر را از طریق متد getRow() بدست می آوریم و در متغییر rc(row count) می ریزیم. در آخر مکان نمای rs را به ابتدای rs می فرستیم. سپس طبق الگوریتم زیر توسط حلقه ی while متغییر rs را از ابتدا تا انتها پیمایش می کند و یک متغییر برای سطر می گیریم که هر بار در حلقه ی while اضافه می شود و به ازای هر سطر، هر ستون مقادیر بانک را به آرایه ی دوبعدی data وارد می کند و در پایان مانند کدهای پایانی مثال قبل، به JTable پاس می دهد.
کدهای آن به صورت زیر می باشد:
private void btnShowActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
ResultSet rs= st.executeQuery("select * from student");
String[] Header = {"تلفن ","سال تولد "," شهر ", "نام خانوادگی ", "نام "," کد ملی "};
rs.last();
int rc=rs.getRow();
rs.beforeFirst();
int cc=6;
String[][] data= new String[rc][cc];
int i=0;
while (rs.next()) {
data[i][5]=rs.getString("sid");
data[i][4]=rs.getString("sname");
data[i][3]=rs.getString("sfamily");
data[i][2]=rs.getString("scity");
data[i][1]=rs.getString("birthyear");
data[i][0]=rs.getString("tell");
i++;
}
jTable1=new JTable(data, Header);
jScrollPane1.setViewportView(jTable1);
rs.close();
st.close();
con.close();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
در مثال بالا کد ها را داخل try/catch می نویسیم و دستور زیر را داخل بلوک catch می نویسیم تا خطا ها را نمایش دهد:try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
ResultSet rs= st.executeQuery("select * from student");
String[] Header = {"تلفن ","سال تولد "," شهر ", "نام خانوادگی ", "نام "," کد ملی "};
rs.last();
int rc=rs.getRow();
rs.beforeFirst();
int cc=6;
String[][] data= new String[rc][cc];
int i=0;
while (rs.next()) {
data[i][5]=rs.getString("sid");
data[i][4]=rs.getString("sname");
data[i][3]=rs.getString("sfamily");
data[i][2]=rs.getString("scity");
data[i][1]=rs.getString("birthyear");
data[i][0]=rs.getString("tell");
i++;
}
jTable1=new JTable(data, Header);
jScrollPane1.setViewportView(jTable1);
rs.close();
st.close();
con.close();
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
JOptionPane.showMessageDialog(null, ex.getMessage());
نکته: برای اینکه ستون ها برعکس مثال قبل از راست به چپ شود و مقادیر sid و sname و... از راست به چپ قرار گیرد، درون حلقه ی while ، مقدار بعد دوم یا همان بعد ستون را از 5 به 0 نوشتیم.خروجی آن به صورت زیر می باشد:
درج در بانک
در این مثال می خواهیم داده ها را وارد جدول student کنیم. چون ستون کلید اصلی است و مقدار null نمی پذیرد، به طور اجباری باید به این فیلد داده وارد کنیم. برای درج اطلاعات به بانک ابتدا به یک فرم برای ورود اطلاعات احتیاج داریم. کلاس JFrame جدیدی به نام darj ایجاد می کنیم و فرم زیر را در آن طراحی می کنیم تا با زدن دکمه ی ok اطلاعات وارد بانک شود. (بعد از آن برای تست صحت این کار از بخش قبل کمک می گیریم تا نمایش دهد. در بخش قبل کلاس JFrame جداگانه به نام BankTOjtable برای نمایش اطلاعات بانک داشتیم).نام textfild دوم را به snametf و
نام textfild سوم را به sfamilytf و
نام textfild چهارم را به scitytf و
نام textfild پنجم را به birthyeartf و
نام textfild آخر را به telltf تغییر می دهیم. و در کد از این نامها استفاده می کنیم.
چون همه ی این کارها با زدن دکمه ی ok انجام می شود، در نتیجه یک رویداد داریم و باید از طریق مسیر زیر (یا با دابل کلیک روی دکمه ی ok در بخش design) وارد بخش Actionperformed آن شویم و کدهای مربوطه را وارد کنیم:
برای اینکه داده ها را از فرم وارد بانک کنیم، نیاز به یکسری دستورات sql داریم که از توضیحات کامل آن صرفه نظر می کنیم.
ابتدا یک متغییر از نوع string به نام sql تعریف می کنیم.
دستور INSERT INTO : یک ردیف جدید به جدولی از بانک موجود اضافه می کند.
String sql= "INSERT INTO Student(sid,sname,sfamily,scity,birthyear,tell) "
+ "values(%s,'%s','%s','%s',%s,'%s')";
در این دستور بعد از کلمه ی کلیدی INSERT INTO نام جدولی از بانک که می خواهیم به آن ردیفی اضافه کنیم را می نویسیم و بعد از آن ستون های آن جدول را به ترتیب می نویسیم (sid,sname,sfamily,scity,birthyear,tell) و بعد از آن کلمه ی کلیدی values رامی نویسیم. بعد از آن به تعداد ستون ها جا می گذاریم و بجای مقدار آن %s قرار می دهیم و برای هر ستونی که مقدار رشته می پذیرد، %s را داخل ‘ ’ قرار می دهیم. مانند'%s' .
از طریق دستور زیر :
sql=String.format(sql,sidtf.getText(),snametf.getText(),sfamilytf.getText(),
scitytf.getText(),birthyeartf.getText(),telltf.getText());
مقدارtextfild اول یعنی sidtf را می گیرد(با استفاده از دستور getText()) و به ستون اول در جدول(sid) می دهد و
مقدارtextfild دوم یعنی snametf را می گیرد و به ستون دوم در جدول(sname ) می دهد و
مقدارtextfild سوم یعنی sfamilytf را می گیرد و به ستون سوم در جدول(sfamily) می دهد و
مقدارtextfild چهارم یعنی scitytf را می گیرد و به ستون چهارم در جدول(scity) می دهد و
مقدارtextfild پنجم یعنی birthyeartf را می گیرد و به ستون پنجم در جدول(birthyear) می دهد و
مقدارtextfild آخر یعنی telltf را می گیرد و به ستون آخر در جدول(tell) می دهد.(با استفاده از دستور format)
و در آخر st با فرمان sql، execute می کند. ; st.execute(sql)
کد های این بخش به صورت زیر می باشد.
private void okbtnActionPerformed(java.awt.event.ActionEvent evt) {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
String sql= "INSERT INTO Student(sid,sname,sfamily,scity,birthyear,tell) "
+ "values(%s,'%s','%s','%s',%s,'%s')";
sql=String.format(sql,sidtf.getText(),snametf.getText(),sfamilytf.getText(),
scitytf.getText(),birthyeartf.getText(),telltf.getText());
st.execute(sql);
st.close();
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
خروجی آن به صورت زیر می باشد:try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
String url= "jdbc:mysql://localhost:3306/db1?user=root&password=123";
Connection con=DriverManager.getConnection(url);
Statement st = con.createStatement();
String sql= "INSERT INTO Student(sid,sname,sfamily,scity,birthyear,tell) "
+ "values(%s,'%s','%s','%s',%s,'%s')";
sql=String.format(sql,sidtf.getText(),snametf.getText(),sfamilytf.getText(),
scitytf.getText(),birthyeartf.getText(),telltf.getText());
st.execute(sql);
st.close();
con.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e);
}
}
برای این منظور دوکار باید انجام شود:
1- وارد کلاس BankTOjtable می شویم و در فرم آن روی دکمه ی "جدید" دابل کلیک می کنیم و وارد btnnewActionPerformed می شویم و کد زیر را به آن وارد می کنیم:
private void btnnewActionPerformed(java.awt.event.ActionEvent evt) {
darj newdarj= new darj();
newdarj.setVisible(true);
}
با فشرده شدن دکمه ی "جدید" ، از کلاس darj نمونه می گیرد(newdarj) و سپس visible آن را true می کند تا با زدن دکمه ی "جدید" ، کلاس darj اجرا شود و فرم آن باز شود.
2- وارد کلاس darj می شویم و در بخش design در قسمت properties مربوط به شی فرم، قسمت defaultClose آن را DISPOSE قرار می دهیم نا با بسته شدن این فرم، از اجرای پروژه خارج نشویم و فقط این فرم بسته شود و فرم نمایش باز باقی بماند.
/ج