26
26
* It's only if you use the non jdbc facilities, do you have to take this into
27
27
* account.
28
28
*
29
+ * Note: For PostgreSQL 6.4, the driver is now Thread safe, so this example
30
+ * application has been updated to use multiple threads, especially in the
31
+ * image storing and retrieving methods.
29
32
*/
30
33
31
34
public class ImageViewer implements ItemListener
@@ -42,8 +45,15 @@ public class ImageViewer implements ItemListener
42
45
// This is a simple component to display our image
43
46
public class imageCanvas extends Canvas
44
47
{
48
+ // holds the image
45
49
private Image image ;
46
50
51
+ // holds the background buffer
52
+ private Image bkg ;
53
+
54
+ // the size of the buffer
55
+ private Dimension size ;
56
+
47
57
public imageCanvas ()
48
58
{
49
59
image =null ;
@@ -71,14 +81,35 @@ public void update(Graphics g)
71
81
paint (g );
72
82
}
73
83
74
- public void paint (Graphics g )
84
+ /**
85
+ * Paints the image, using double buffering to prevent screen flicker
86
+ */
87
+ public void paint (Graphics gr )
75
88
{
89
+ Dimension s = getSize ();
90
+
91
+ if (size ==null || bkg ==null || !s .equals (size )) {
92
+ size = s ;
93
+ bkg = createImage (size .width ,size .height );
94
+ }
95
+
96
+ // now set the background
97
+ Graphics g = bkg .getGraphics ();
76
98
g .setColor (Color .gray );
77
- g .fillRect (0 ,0 ,getSize () .width ,getSize () .height );
99
+ g .fillRect (0 ,0 ,s .width ,s .height );
78
100
101
+ // now paint the image over the background
79
102
if (image !=null )
80
103
g .drawImage (image ,0 ,0 ,this );
104
+
105
+ // dispose the graphics instance
106
+ g .dispose ();
107
+
108
+ // paint the image onto the component
109
+ gr .drawImage (bkg ,0 ,0 ,this );
110
+
81
111
}
112
+
82
113
}
83
114
84
115
public ImageViewer (Frame f ,String url ,String user ,String password ) throws ClassNotFoundException , FileNotFoundException , IOException , SQLException
@@ -197,9 +228,8 @@ public void close()
197
228
}
198
229
199
230
/**
200
- * This imports an image into the database.
201
- *
202
- * This is the most efficient method, using the large object extension.
231
+ * This imports an image into the database, using a Thread to do this in the
232
+ * background.
203
233
*/
204
234
public void importImage ()
205
235
{
@@ -209,51 +239,92 @@ public void importImage()
209
239
String dir = d .getDirectory ();
210
240
d .dispose ();
211
241
212
- // Now the real import stuff
213
- if (name !=null && dir !=null ) {
214
- try {
215
- System .out .println ("Importing file" );
216
- // A temporary buffer - this can be as large as you like
217
- byte buf [] = new byte [2048 ];
218
-
219
- // Open the file
220
- System .out .println ("Opening file " +dir +"/" +name );
221
- FileInputStream fis = new FileInputStream (new File (dir ,name ));
222
-
223
- // Gain access to large objects
224
- System .out .println ("Gaining LOAPI" );
225
-
226
- // Now create the large object
227
- System .out .println ("creating blob" );
228
- int oid = lom .create ();
229
-
230
- System .out .println ("Opening " +oid );
231
- LargeObject blob = lom .open (oid );
242
+ // now start the true importer
243
+ Thread t = new importer (db ,name ,dir );
244
+ //t.setPriority(Thread.MAX_PRIORITY);
245
+ t .start ();
246
+ }
247
+
248
+ /**
249
+ * This is an example of using a thread to import a file into a Large Object.
250
+ * It uses the Large Object extension, to write blocks of the file to the
251
+ * database.
252
+ */
253
+ class importer extends Thread
254
+ {
255
+ String name ,dir ;
256
+ Connection db ;
257
+
258
+ public importer (Connection db ,String name ,String dir ) {
259
+ this .db = db ;
260
+ this .name = name ;
261
+ this .dir = dir ;
262
+ }
263
+
264
+ public void run () {
265
+
266
+ // Now the real import stuff
267
+ if (name !=null && dir !=null ) {
268
+ Statement stat = null ;
232
269
233
- // Now copy the file into the object.
234
- //
235
- // Note: we dont use write(buf), as the last block is rarely the same
236
- // size as our buffer, so we have to use the amount read.
237
- System .out .println ("Importing file" );
238
- int s ,t =0 ;
239
- while ((s =fis .read (buf ,0 ,buf .length ))>0 ) {
240
- System .out .println ("Block s=" +s +" t=" +t );t +=s ;
241
- blob .write (buf ,0 ,s );
270
+ try {
271
+ // fetch the large object manager
272
+ LargeObjectManager lom = ((postgresql .Connection )db ).getLargeObjectAPI ();
273
+
274
+ System .out .println ("Importing file" );
275
+ // A temporary buffer - this can be as large as you like
276
+ byte buf [] = new byte [2048 ];
277
+
278
+ // Open the file
279
+ System .out .println ("Opening file " +dir +"/" +name );
280
+ FileInputStream fis = new FileInputStream (new File (dir ,name ));
281
+
282
+ // Gain access to large objects
283
+ System .out .println ("Gaining LOAPI" );
284
+
285
+ // Now create the large object
286
+ System .out .println ("creating blob" );
287
+ int oid = lom .create ();
288
+
289
+ System .out .println ("Opening " +oid );
290
+ LargeObject blob = lom .open (oid );
291
+
292
+ // Now copy the file into the object.
293
+ //
294
+ // Note: we dont use write(buf), as the last block is rarely the same
295
+ // size as our buffer, so we have to use the amount read.
296
+ System .out .println ("Importing file" );
297
+ int s ,t =0 ;
298
+ while ((s =fis .read (buf ,0 ,buf .length ))>0 ) {
299
+ System .out .println ("Block s=" +s +" t=" +t );t +=s ;
300
+ blob .write (buf ,0 ,s );
301
+ }
302
+
303
+ // Close the object
304
+ System .out .println ("Closing blob" );
305
+ blob .close ();
306
+
307
+ // Now store the entry into the table
308
+
309
+ // As we are a different thread to the other window, we must use
310
+ // our own thread
311
+ stat = db .createStatement ();
312
+ stat .executeUpdate ("insert into images values ('" +name +"'," +oid +")" );
313
+
314
+ // Finally refresh the names list, and display the current image
315
+ ImageViewer .this .refreshList ();
316
+ ImageViewer .this .displayImage (name );
317
+ } catch (Exception ex ) {
318
+ label .setText (ex .toString ());
319
+ } finally {
320
+ // ensure the statement is closed after us
321
+ try {
322
+ if (stat != null )
323
+ stat .close ();
324
+ } catch (SQLException se ) {
325
+ System .err .println ("closing of Statement failed" );
326
+ }
242
327
}
243
-
244
- // Close the object
245
- System .out .println ("Closing blob" );
246
- blob .close ();
247
-
248
- // Now store the entry into the table
249
- stat .executeUpdate ("insert into images values ('" +name +"'," +oid +")" );
250
- stat .close ();
251
-
252
- // Finally refresh the names list, and display the current image
253
- refreshList ();
254
- displayImage (name );
255
- } catch (Exception ex ) {
256
- label .setText (ex .toString ());
257
328
}
258
329
}
259
330
}
@@ -364,7 +435,7 @@ public static void main(String args[])
364
435
}
365
436
366
437
try {
367
- Frame frame = new Frame ("PostgreSQL ImageViewer v6.3 rev 1" );
438
+ Frame frame = new Frame ("PostgreSQL ImageViewer v6.4 rev 1" );
368
439
frame .setLayout (new BorderLayout ());
369
440
ImageViewer viewer = new ImageViewer (frame ,args [0 ],args [1 ],args [2 ]);
370
441
frame .pack ();
0 commit comments