View Full Version : نمایش عکس و فراخوانی از jtable
cnmeysam
چهارشنبه 01 شهریور 1396, 15:53 عصر
سلام
من یه برنامه نوشتم که چند تا تکت باکس و یه لیبل برای نمایش عکس داره
بعد از انتخاب عکس عکس رو توی لیبل نمایش میده
ولی بعد از ثبت توی دیتابیس و لود شدن دیتاها توی تیبل نمیتونم عکس ثبت شده رو توی لیبل نشون بدم
کانکشن رو توی یه فایل dll ذخیره کردم و از اونجا میخونه نمیخوام کانکشنم دستی بشه
کدی که بعد از کلیک روی سطرهای تیبل نوشتم اینه:
private void datatableMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
int i = datatable.getSelectedRow();
txtfile.setText(datatable.getValueAt(i, 1).toString());
//لیبل عکس
String test = datatable.getValueAt(i, 2).toString();
byte[] bytes = test.getBytes();
byte[] img = bytes;
ImageIcon image = new ImageIcon(img);
Image im = image.getImage();
Image myImg = im.getScaledInstance(lblpic.getWidth(), lblpic.getHeight(),Image.SCALE_SMOOTH);
ImageIcon newImage = new ImageIcon(myImg);
lblpic.setIcon(newImage);
//لیبل عکس
datePic.setDate(datatable.getValueAt(i, 3).toString());
txtdescriptions.setText(datatable.getValueAt(i, 4).toString());
}
متاسفانه نتونستم کاری کنم عکس رو توی لیبل (lblpic)نمایش بده با راهنما قسمت لیبل عکس رو مشخص کردم این هم عکس ظاهر برنامه
146112
میشه کمکم کنید؟
vahid-p
چهارشنبه 01 شهریور 1396, 17:00 عصر
خب عکس که در دیتابیس ذخیره کردید Blob هست که باید اطلاعاتش رو بخونید و به Image تبدیل کنید. که اینکار رو تو لینک زیر خیلی خلاصه توضیح داده:
https://stackoverflow.com/questions/30751964
cnmeysam
چهارشنبه 01 شهریور 1396, 17:03 عصر
خب وقتی یک بار فراخوانی کردم آوردم توی تیبل چرا باید دوباره فراخوانی کنم؟
من میخوام وقتی توی تیبل رویش کلیک کردم مثل تکست ها که خودشون میان پر میشن عکس هم خودش بیاد راهی نداره بعد کلیک روی آیتم مورد نظرم توی تیبل عکسش هم لود بشه؟
cnmeysam
چهارشنبه 01 شهریور 1396, 18:01 عصر
خب عکس که در دیتابیس ذخیره کردید Blob هست که باید اطلاعاتش رو بخونید و به Image تبدیل کنید. که اینکار رو تو لینک زیر خیلی خلاصه توضیح داده:
https://stackoverflow.com/questions/30751964
به این کد رسیدم ولی باز هم عکس رو نشون نمیده میشه بگید مشکل کجاست؟ فایل Miscsied.dll توش کانکشن هست و از اونجا میخونه اطلاعت اتصال به دیتابیس رو
private void datatableMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
int i = datatable.getSelectedRow();
lblID.setText(datatable.getValueAt(i, 0).toString());
txtfile.setText(datatable.getValueAt(i, 1).toString());
//لیبل عکس
try{
FileReader reader = new FileReader("Miscsied.dll");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
String url =line;
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url);
Statement st =con.createStatement();
ResultSet resultSet = st.executeQuery
("select * from tbl_pic WHERE fileid='"+txtfile.getText()+"'AND ID='"+lblID.getText()+"'");
byte[] image = null;
while(resultSet.next()) {
image = resultSet.getBytes("pic");
}
Image img = Toolkit.getDefaultToolkit().createImage(image);
ImageIcon icon =new ImageIcon(img);
lblpic.setIcon(icon);
}
}catch (Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
//لیبل عکس
datePic.setDate(datatable.getValueAt(i, 3).toString());
txtdescriptions.setText(datatable.getValueAt(i, 4).toString());
}
vahid-p
چهارشنبه 01 شهریور 1396, 18:48 عصر
شما از چیزی که در لینکی که دادم استفاده نکردید.
نوشتید:
resultSet.getBytes("pic");
خب به جاش همون getBlob استفاده کنید (همچنین نیازی به while نیست چون باید یکی باشه وگرنه عکس اولی از دست میره).
بعد از اون جریان ورودی میگیرید و تصویر رو میسازید. شما اینکار رو نکردید. طبق لینکی که دادم برید، ببینید جواب میگیرید یا نه
ضمنا چک کنید اصلا نتیجه ای رو بر میگردونه یا نه. چون اگر از آی دی استفاده میکنید چرا دو تا شرط گذاشتید تو SQL تون؟ آی دی باید یک عنصر رو مشخص کنه دیگه درسته؟
این از قضیه لود کردنش.
شما داده های عکس رو نمیتونید تو جدول ذخیره کنید و برای همین دوباره باید Query بزنید تا عکس رو بخونید. اگر نمیخواید اینکار رو بکنید یک HashMap درست کنید که کلیدش ID باشه و مقدارش عکسهای از نوع BufferedImage باشه. به این ترتیب شما عکس ها رو همراه تشکیل لیست میخونید و لازم نیست دفعه بعد Query بزنید و راحت تمام عکس ها درون HashMap ذخیره شدن. جدول امکان ذخیره متن رو داره اما عکس رو نه و برای همین از یک داده ساختار دیگه ای استفاده کردیم
cnmeysam
چهارشنبه 01 شهریور 1396, 20:35 عصر
باز هم نشد میشه کد رو برام اصلاح کنید شاید متوجه بشم اشکال کارم چیه این الان کد منه:
private void datatableMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
int i = datatable.getSelectedRow();
lblID.setText(datatable.getValueAt(i, 0).toString());
txtfile.setText(datatable.getValueAt(i, 1).toString());
//لیبل عکس
try{
FileReader reader = new FileReader("Miscsied.dll");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
String url =line;
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = DriverManager.getConnection(url);
Statement st =con.createStatement();
//ResultSet resultSet = st.executeQuery ("select * from tbl_pic WHERE fileid='"+txtfile.getText()+"'AND ID='"+lblID.getText()+"'");
ResultSet rs = st.executeQuery("select * from tbl_pic WHERE fileid='"+txtfile.getText()+"'AND ID='"+lblID.getText()+"'");
rs.next();
java.sql.Blob blob = rs.getBlob("pic");
InputStream in = blob.getBinaryStream();
BufferedImage image = ImageIO.read(in);
ImageIcon icon =new ImageIcon(image);
lblpic.setIcon(icon);
}
}catch (Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
//لیبل عکس
datePic.setDate(datatable.getValueAt(i, 3).toString());
txtdescriptions.setText(datatable.getValueAt(i, 4).toString());
}
vahid-p
چهارشنبه 01 شهریور 1396, 23:38 عصر
این موضوع که پرسیدم رو بررسی نکردید، اگر بررسی کردید نتیجش رو نگفتید:
ضمنا چک کنید اصلا نتیجه ای رو بر میگردونه یا نه. چون اگر از آی دی استفاده میکنید چرا دو تا شرط گذاشتید تو SQL تون؟ آی دی باید یک عنصر رو مشخص کنه دیگه درسته؟
من کد شما رو استفاده کردم و کاملا جواب میده (به صورت عملی تست کردم و عکس رو نمایش میده). احتمال میدم اصلا sql تون خروجی نداره و برای همین هم چیزی نمایش داده نمیشه و خطا میده.
یکم کد شما رو دستکاری کردم برای اینکه رو سیستم خودم تست کنم، شما هم از یک شرط if-else برای rs.next استفاده کنید ببینید اصلا resultset خالی هست یا نه.
try { Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb", "root", "");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from images WHERE `id`=1");
if (rs.next()) {
java.sql.Blob blob = rs.getBlob("img");
InputStream in = blob.getBinaryStream();
BufferedImage image = ImageIO.read(in);
ImageIcon icon = new ImageIcon(image);
lblpic.setIcon(icon);
} else {
System.out.println("Not found!");
}
} catch (Exception ex) {
Logger.getLogger(this.getName()).log(Level.SEVERE, null, ex);
}
cnmeysam
چهارشنبه 01 شهریور 1396, 23:44 عصر
این موضوع که پرسیدم رو بررسی نکردید، اگر بررسی کردید نتیجش رو نگفتید:
من کد شما رو استفاده کردم و کاملا جواب میده (به صورت عملی تست کردم و عکس رو نمایش میده). احتمال میدم اصلا sql تون خروجی نداره و برای همین هم چیزی نمایش داده نمیشه و خطا میده.
یکم کد شما رو دستکاری کردم برای اینکه رو سیستم خودم تست کنم، شما هم از یک شرط if-else برای rs.next استفاده کنید ببینید اصلا resultset خالی هست یا نه.
try { Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/javadb", "root", "");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select * from images WHERE `id`=1");
if (rs.next()) {
java.sql.Blob blob = rs.getBlob("img");
InputStream in = blob.getBinaryStream();
BufferedImage image = ImageIO.read(in);
ImageIcon icon = new ImageIcon(image);
lblpic.setIcon(icon);
} else {
System.out.println("Not found!");
}
} catch (Exception ex) {
Logger.getLogger(this.getName()).log(Level.SEVERE, null, ex);
}
یکی شماره پرونده بیماره یکی ID عکس چون ممکنه یک بیمار چند تا عکس داشته باشه نمیشه که همشون یکجا نمایش داده بشن باید فقط عکسی که روش کلیک شده نمایش داده بشه برای همین 2 تا شرط داره
cnmeysam
چهارشنبه 01 شهریور 1396, 23:48 عصر
دیگه مغزم کار نمیکنه باز هم نشد دقیقا کد شما رو گذاشتم عکس رو ببینید شاید متوجه بشید
146115
این هم دیتابیسمه
146116
vahid-p
چهارشنبه 01 شهریور 1396, 23:50 عصر
خب برای همین اگر فقط شماره پروندش رو سرچ کنید یک عکس میاد. حالا اینا مهم نیست، من نمیدونم دیتابیس رو چطور طراحی کردید. فقط شرطی که گفتم رو تو کدتون بذارید اول مشخص بشه resultset خالی هست یا نه. اگر خالی بود مشخصه query تون اشتباهه و مشکل از کد نیست
همچنین قسمت catch کدتون رو تغییر بدید به
Logger.getLogger(this.getName()).log(Level.SEVERE, null, ex);
اینجوری که شما قسمت catch رو نوشتید هیچ اطلاعاتی نمیده بهمون.
cnmeysam
پنج شنبه 02 شهریور 1396, 00:05 صبح
اینارو میده
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at java.util.Hashtable.get(Hashtable.java:363)
at java.util.logging.LogManager$LoggerContext.findLog ger(LogManager.java:693)
at java.util.logging.LogManager.getLogger(LogManager. java:1226)
at java.util.logging.LogManager.demandLogger(LogManag er.java:551)
at java.util.logging.Logger.demandLogger(Logger.java: 455)
at java.util.logging.Logger.getLogger(Logger.java:502 )
at PI.picture.datatableMouseClicked(picture.java:627)
at PI.picture.access$500(picture.java:30)
at PI.picture$6.mouseClicked(picture.java:375)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEvent Multicaster.java:270)
at java.awt.Component.processMouseEvent(Component.jav a:6536)
at javax.swing.JComponent.processMouseEvent(JComponen t.java:3324)
at java.awt.Component.processEvent(Component.java:629 8)
at java.awt.Container.processEvent(Container.java:223 6)
at java.awt.Component.dispatchEventImpl(Component.jav a:4889)
at java.awt.Container.dispatchEventImpl(Container.jav a:2294)
at java.awt.Component.dispatchEvent(Component.java:47 11)
at java.awt.LightweightDispatcher.retargetMouseEvent( Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(C ontainer.java:4534)
at java.awt.LightweightDispatcher.dispatchEvent(Conta iner.java:4466)
at java.awt.Container.dispatchEventImpl(Container.jav a:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2746 )
at java.awt.Component.dispatchEvent(Component.java:47 11)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.j ava:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessI mpl.doIntersectionPrivilege(ProtectionDomain.java: 80)
at java.security.ProtectionDomain$JavaSecurityAccessI mpl.doIntersectionPrivilege(ProtectionDomain.java: 90)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessI mpl.doIntersectionPrivilege(ProtectionDomain.java: 80)
at java.awt.EventQueue.dispatchEvent(EventQueue.java: 728)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(E ventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispa tchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispa tchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThre ad.java:82)
vahid-p
پنج شنبه 02 شهریور 1396, 00:10 صبح
خب اینکه ربطی به قسمت SQL و نمایش دادنش نداره. یکی از کامپوننت ها یا از این Hashtable نال هست. اینو باید تو کد ببینی چرا null هست. من از رو کدتون نمیتونم حدس بزنم. خواستید کل سورس پروژتون رو به صورت zip بذارید چک کنم
cnmeysam
پنج شنبه 02 شهریور 1396, 00:29 صبح
این کل پروژست تا الان دیتابیسشم پیوست کردم
توی فرم لاگین اول تنظیمات اتصال به دیتابیس رو ثبت کنید تا فایل dll ساخته بشه که به دیتابیس بتونه وصل بشه
لطفا چک کنید اگه جاییش اشکالی داره بهم بگید ممنون میشم آخه اولین کارمه و تاحالا برنامه نویسی نکردم مخصوصا با جاوا همش رو هم توی نت یاد گرفتم:خجالت:
vahid-p
پنج شنبه 02 شهریور 1396, 01:52 صبح
مشکل از لود کردن عکس نیست. چون اگر شما در دیتابیس برید و سطری که ایجاد شده رو نگاه کنید قسمت pic در حد چند بایت هست و اگر دانلود کنید میبینید محتواش یه چیزی شبیه اینه:
java.io.FileInputStream@36279b8
حتی اون عکسی که خودتون گذاشتید، ستون pic رو ببینید: (این کل داده ای است که در پایگاه داده ذخیره شده و نه داده عکس!) شما نوع آبجکت رو ذخیره کردید نه داده هاش رو. پس اگر در دیتابیس دستی یه عکس جای قبلی آپلود کنید (با phpmyadmin) و بیایید برنامه رو ران کنید میبینید عکس بالا میاد. پس باید قسمت ذخیره کردن عکس رو درستش کنید.
http://barnamenevis.org/attachment.php?attachmentid=146115&d=1503517712
برای همین هم در قسمت
BufferedImage image = ImageIO.read(in);
مقدار image برابر null هست. چون اصلا داده عکس نیست.
cnmeysam
پنج شنبه 02 شهریور 1396, 01:57 صبح
کد ذخیره عکسم اینه اشتباهم کجاست؟؟؟
private void btnregisterActionPerformed(java.awt.event.ActionEv ent evt) {
// TODO add your handling code here:
try{
String _file = txtfile.getText();
InputStream _pic = new FileInputStream(new File(s));
/*Icon icon = lblpic.getIcon();
BufferedImage _image = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(),BufferedImage.TYPE_INT_RGB);*/
String _date = datePic.getDate();
String _desc = txtdescriptions.getText();
String sql = "insert into tbl_pic (fileid,pic,date,description)"
+ "values ('%s','%s','%s','%s')";
sql = String.format(sql, _file, _pic, _date, _desc);
Clas.class_register obj = new Clas.class_register();
obj.NonQuery(sql);
lbl_error.setText("ثبت شد!");
}
catch(Exception ex){
ex.printStackTrace();
}
}
vahid-p
پنج شنبه 02 شهریور 1396, 02:06 صبح
از این لینک استفاده کنید:
http://www.roseindia.net/jdbc/save_image.shtml
که از preparestatement استفاده کرده و داده های عکس رو مستقیم از طریق setBinaryStream بهش پاس کنید.
من که متوجه منطق کدتون نشدم. گویا یه اسم فایل میخونید و داده ها رو از تو اون فایل میخونید (در صورتی که نیازی به ذخیره کردن عکس در فایل نیست) و بعد آبجکت _pic که از نوع InputStream رو از طریق String.format در کوئری قرار دادید!!! خب کاری که String.format میکنه برای هر آبجکت متد toString اش رو صدا میزنه و میدونید که برای آبجکت ها به صورت پیشفرض نام کلاس و یک شماره بعد از @ میاد که شماره آبجکت هست!
پس نباید انتظار داشته باشید کار کنه.
شما مستقیم هر کدی رو رو پروژه اصلی ننویسید. ابتدا یک پروژه کوچک ایجاد کنید هر کدی که ازش جواب گرفتید وارد کد اصلی کنید. الان یک پروژه ساده بنویسید که عکس رو داخل دیتابیس ذخیره کنه وقتی از صحت عملکردش مطمئن شدید در کدتون استفاده کنید. نیازی هم نیست پیچیدش کنید و ورودی از کاربر بگیره و... . نه یک آدرس مستقیم بدید فقط عکس رو به صورت Image ایجاد کنه.
به هر حال با یکم تلاش خودتون میتونید بنویسید.
cnmeysam
پنج شنبه 02 شهریور 1396, 03:06 صبح
این شد کد ثبت
private void btnregisterActionPerformed(java.awt.event.ActionEv ent evt) {
// TODO add your handling code here:
PreparedStatement psmnt = null;
Connection connection = null;
ResultSet rs = null;
FileInputStream fis;
try {
FileReader reader = new FileReader("Miscsied.dll");
BufferedReader bufferedReader = new BufferedReader(reader);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
String url =line;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(url);
File image = new File(lblpath.getText());
psmnt = connection.prepareStatement
("insert into tbl_pic (fileid,pic,date,description) "+ "values(?,?,?,?)");
psmnt.setString(1,txtfile.getText());
psmnt.setString(3,datePic.getDate());
psmnt.setString(4,txtdescriptions.getText());
fis = new FileInputStream(image);
psmnt.setBinaryStream(2, (InputStream)fis, (int)(image.length()));
int s = psmnt.executeUpdate();
if(s>0) {
System.out.println("Uploaded successfully !");
lbl_error.setText("ثبت شد!");
}
else {
System.out.println("unsucessfull to upload image.");
lbl_error.setText("ثبت نشد!");
}
}
}catch (Exception ex) {
System.out.println("Found some error : "+ex);
}
finally {
// close all the connections.
}
}
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.