ImageViewer.java
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:12k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. package example;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import java.io.*;
  5. import java.sql.*;
  6. import postgresql.largeobject.*;
  7. /**
  8.  * This example is a small application that stores and displays images
  9.  * held on a postgresql database.
  10.  *
  11.  * Before running this application, you need to create a database, and
  12.  * on the first time you run it, select "Initialise" in the "PostgreSQL"
  13.  * menu.
  14.  *
  15.  * Important note: You will notice we import the postgresql.largeobject
  16.  * package, but don't import the postgresql package. The reason for this is
  17.  * that importing postgresql can confuse javac (we have conflicting class names
  18.  * in postgresql.* and java.sql.*). This doesn't cause any problems, as long
  19.  * as no code imports postgresql.
  20.  *
  21.  * Under normal circumstances, code using any jdbc driver only needs to import
  22.  * java.sql, so this isn't a problem.
  23.  *
  24.  * It's only if you use the non jdbc facilities, do you have to take this into
  25.  * account.
  26.  *
  27.  * Note: For PostgreSQL 6.4, the driver is now Thread safe, so this example
  28.  * application has been updated to use multiple threads, especially in the
  29.  * image storing and retrieving methods.
  30.  */
  31. public class ImageViewer implements ItemListener
  32. {
  33.   Connection db;
  34.   Statement stat;
  35.   LargeObjectManager lom;
  36.   Frame frame;
  37.   Label label; // Label used to display the current name
  38.   List list; // The list of available images
  39.   imageCanvas canvas; // Canvas used to display the image
  40.   String currentImage; // The current images name
  41.   
  42.   // This is a simple component to display our image
  43.   public class imageCanvas extends Canvas
  44.   {
  45.     // holds the image
  46.     private Image image;
  47.     
  48.     // holds the background buffer
  49.     private Image bkg;
  50.     
  51.     // the size of the buffer
  52.     private Dimension size;
  53.     
  54.     public imageCanvas()
  55.     {
  56.       image=null;
  57.     }
  58.     
  59.     public void setImage(Image img)
  60.     {
  61.       image=img;
  62.       repaint();
  63.     }
  64.     
  65.     // This defines our minimum size
  66.     public Dimension getMinimumSize()
  67.     {
  68.       return new Dimension(400,400);
  69.     }
  70.     
  71.     public Dimension getPreferedSize()
  72.     {
  73.       return getMinimumSize();
  74.     }
  75.     
  76.     public void update(Graphics g)
  77.     {
  78.       paint(g);
  79.     }
  80.     
  81.     /**
  82.      * Paints the image, using double buffering to prevent screen flicker
  83.      */
  84.     public void paint(Graphics gr)
  85.     {
  86.       Dimension s = getSize();
  87.       
  88.       if(size==null || bkg==null || !s.equals(size)) {
  89. size = s;
  90. bkg = createImage(size.width,size.height);
  91.       }
  92.       
  93.       // now set the background
  94.       Graphics g = bkg.getGraphics();
  95.       g.setColor(Color.gray);
  96.       g.fillRect(0,0,s.width,s.height);
  97.       
  98.       // now paint the image over the background
  99.       if(image!=null)
  100. g.drawImage(image,0,0,this);
  101.       
  102.       // dispose the graphics instance
  103.       g.dispose();
  104.       
  105.       // paint the image onto the component
  106.       gr.drawImage(bkg,0,0,this);
  107.       
  108.     }
  109.     
  110.   }
  111.   
  112.   public ImageViewer(Frame f,String url,String user,String password) throws ClassNotFoundException, FileNotFoundException, IOException, SQLException
  113.   {
  114.     frame = f;
  115.     
  116.     MenuBar mb = new MenuBar();
  117.     Menu m;
  118.     MenuItem i;
  119.     
  120.     f.setMenuBar(mb);
  121.     mb.add(m = new Menu("PostgreSQL"));
  122.     m.add(i= new MenuItem("Initialise"));
  123.     i.addActionListener(new ActionListener() {
  124.       public void actionPerformed(ActionEvent e) {
  125. ImageViewer.this.init();
  126.       }
  127.     });
  128.     
  129.     m.add(i= new MenuItem("Exit"));
  130.     ActionListener exitListener = new ActionListener() {
  131.       public void actionPerformed(ActionEvent e) {
  132. ImageViewer.this.close();
  133.       }
  134.     };
  135.     m.addActionListener(exitListener);
  136.     
  137.     mb.add(m = new Menu("Image"));
  138.     m.add(i= new MenuItem("Import"));
  139.     ActionListener importListener = new ActionListener() {
  140.       public void actionPerformed(ActionEvent e) {
  141. ImageViewer.this.importImage();
  142.       }
  143.     };
  144.     i.addActionListener(importListener);
  145.     
  146.     m.add(i= new MenuItem("Remove"));
  147.     ActionListener removeListener = new ActionListener() {
  148.       public void actionPerformed(ActionEvent e) {
  149. ImageViewer.this.removeImage();
  150.       }
  151.     };
  152.     i.addActionListener(removeListener);
  153.     
  154.     // To the north is a label used to display the current images name
  155.     f.add("North",label = new Label());
  156.     
  157.     // We have a panel to the south of the frame containing the controls
  158.     Panel p = new Panel();
  159.     p.setLayout(new FlowLayout());
  160.     Button b;
  161.     p.add(b=new Button("Refresh List"));
  162.     b.addActionListener(new ActionListener() {
  163.       public void actionPerformed(ActionEvent e) {
  164. ImageViewer.this.refreshList();
  165.       }
  166.     });
  167.     p.add(b=new Button("Import new image"));
  168.     b.addActionListener(importListener);
  169.     p.add(b=new Button("Remove image"));
  170.     b.addActionListener(removeListener);
  171.     p.add(b=new Button("Quit"));
  172.     b.addActionListener(exitListener);
  173.     f.add("South",p);
  174.     
  175.     // And a panel to the west containing the list of available images
  176.     f.add("West",list=new List());
  177.     list.addItemListener(this);
  178.     
  179.     // Finally the centre contains our image
  180.     f.add("Center",canvas = new imageCanvas());
  181.     
  182.     // Load the driver
  183.     Class.forName("postgresql.Driver");
  184.     
  185.     // Connect to database
  186.     System.out.println("Connecting to Database URL = " + url);
  187.     db = DriverManager.getConnection(url, user, password);
  188.     
  189.     // Create a statement
  190.     stat = db.createStatement();
  191.     
  192.     // Set the connection to use transactions
  193.     db.setAutoCommit(false);
  194.     
  195.     // Also, get the LargeObjectManager for this connection
  196.     lom = ((postgresql.Connection)db).getLargeObjectAPI();
  197.     
  198.     // Now refresh the image selection list
  199.     refreshList();
  200.   }
  201.   
  202.   
  203.   /**
  204.    * This method initialises the database by creating a table that contains
  205.    * the image names, and Large Object OID's
  206.    */
  207.   public void init()
  208.   {
  209.     try {
  210.       stat.executeUpdate("create table images (imgname name,imgoid oid)");
  211.       label.setText("Initialised database");
  212.       db.commit();
  213.     } catch(SQLException ex) {
  214.       label.setText(ex.toString());
  215.     }
  216.   }
  217.   
  218.   /**
  219.    * This closes the connection, and ends the application
  220.    */
  221.   public void close()
  222.   {
  223.     try {
  224.       db.close();
  225.     } catch(SQLException ex) {
  226.       System.err.println(ex.toString());
  227.     }
  228.     System.exit(0);
  229.   }
  230.   
  231.   /**
  232.    * This imports an image into the database, using a Thread to do this in the
  233.    * background.
  234.    */
  235.   public void importImage()
  236.   {
  237.     FileDialog d = new FileDialog(frame,"Import Image",FileDialog.LOAD);
  238.     d.setVisible(true);
  239.     String name = d.getFile();
  240.     String dir = d.getDirectory();
  241.     d.dispose();
  242.     
  243.     // now start the true importer
  244.     Thread t = new importer(db,name,dir);
  245.     //t.setPriority(Thread.MAX_PRIORITY);
  246.     t.start();
  247.   }
  248.   
  249.   /**
  250.    * This is an example of using a thread to import a file into a Large Object.
  251.    * It uses the Large Object extension, to write blocks of the file to the
  252.    * database.
  253.    */
  254.   class importer extends Thread
  255.   {
  256.     String name,dir;
  257.     Connection db;
  258.     
  259.     public importer(Connection db,String name,String dir) {
  260.       this.db = db;
  261.       this.name = name;
  262.       this.dir = dir;
  263.     }
  264.     
  265.     public void run() {
  266.       
  267.       // Now the real import stuff
  268.       if(name!=null && dir!=null) {
  269. Statement stat = null;
  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.   db.commit();
  314.   
  315.   // Finally refresh the names list, and display the current image
  316.   ImageViewer.this.refreshList();
  317.   ImageViewer.this.displayImage(name);
  318. } catch(Exception ex) {
  319.   label.setText(ex.toString());
  320. } finally {
  321.   // ensure the statement is closed after us
  322.   try {
  323.     if(stat != null)
  324.       stat.close();
  325.   } catch(SQLException se) {
  326.     System.err.println("closing of Statement failed");
  327.   }
  328. }
  329.       }
  330.     }
  331.   }
  332.   
  333.   /**
  334.    * This refreshes the list of available images
  335.    */
  336.   public void refreshList()
  337.   {
  338.     try {
  339.       // First, we'll run a query, retrieving all of the image names
  340.       ResultSet rs = stat.executeQuery("select imgname from images order by imgname");
  341.       if(rs!=null) {
  342. list.removeAll();
  343. while(rs.next())
  344.   list.addItem(rs.getString(1));
  345. rs.close();
  346.       }
  347.     } catch(SQLException ex) {
  348.       label.setText(ex.toString()+" Have you initialised the database?");
  349.     }
  350.   }
  351.   
  352.   /**
  353.    * This removes an image from the database
  354.    *
  355.    * Note: With postgresql, this is the only way of deleting a large object
  356.    * using Java.
  357.    */
  358.   public void removeImage()
  359.   {
  360.     try {
  361.       // Delete any large objects for the current name
  362.       ResultSet rs = stat.executeQuery("select imgoid from images where imgname='"+currentImage+"'");
  363.       if(rs!=null) {
  364. // Even though there should only be one image, we still have to
  365. // cycle through the ResultSet
  366. while(rs.next()) {
  367.   System.out.println("Got oid "+rs.getInt(1));
  368.   lom.delete(rs.getInt(1));
  369.   System.out.println("Import complete");
  370. }
  371.       }
  372.       rs.close();
  373.       
  374.       // Finally delete any entries for that name
  375.       stat.executeUpdate("delete from images where imgname='"+currentImage+"'");
  376.       db.commit();
  377.       
  378.       label.setText(currentImage+" deleted");
  379.       currentImage=null;
  380.       db.commit();
  381.       refreshList();
  382.     } catch(SQLException ex) {
  383.       label.setText(ex.toString());
  384.     }
  385.   }
  386.   
  387.   /**
  388.    * This displays an image from the database.
  389.    *
  390.    * For images, this is the easiest method.
  391.    */
  392.   public void displayImage(String name)
  393.   {
  394.     try {
  395.       System.out.println("Selecting oid for "+name);
  396.       ResultSet rs = stat.executeQuery("select imgoid from images where imgname='"+name+"'");
  397.       if(rs!=null) {
  398. // Even though there should only be one image, we still have to
  399. // cycle through the ResultSet
  400. while(rs.next()) {
  401.   System.out.println("Got oid "+rs.getInt(1));
  402.   canvas.setImage(canvas.getToolkit().createImage(rs.getBytes(1)));
  403.   System.out.println("Import complete");
  404.   label.setText(currentImage = name);
  405. }
  406.       }
  407.       rs.close();
  408.     } catch(SQLException ex) {
  409.       label.setText(ex.toString());
  410.     }
  411.   }
  412.   
  413.   public void itemStateChanged(ItemEvent e) {
  414.     displayImage(list.getItem(((Integer)e.getItem()).intValue()));
  415.   }
  416.   
  417.   /**
  418.    * This is the command line instructions
  419.    */
  420.   public static void instructions()
  421.   {
  422.     System.err.println("java example.ImageViewer jdbc-url user password");
  423.     System.err.println("nExamples:n");
  424.     System.err.println("java -Djdbc.driver=postgresql.Driver example.ImageViewer jdbc:postgresql:test postgres passwordn");
  425.     
  426.     System.err.println("This example tests the binary large object api of the driver.nBasically, it will allow you to store and view images held in the database.");
  427.     System.err.println("Note: If you are running this for the first time on a particular database,nyou have to select "Initialise" in the "PostgreSQL" menu.nThis will create a table used to store image names.");
  428.   }
  429.   
  430.   /**
  431.    * This is the application entry point
  432.    */
  433.   public static void main(String args[])
  434.   {
  435.     if(args.length!=3) {
  436.       instructions();
  437.       System.exit(1);
  438.     }
  439.     
  440.     try {
  441.       Frame frame = new Frame("PostgreSQL ImageViewer v6.4 rev 1");
  442.       frame.setLayout(new BorderLayout());
  443.       ImageViewer viewer = new ImageViewer(frame,args[0],args[1],args[2]);
  444.       frame.pack();
  445.       frame.setVisible(true);
  446.     } catch(Exception ex) {
  447.       System.err.println("Exception caught.n"+ex);
  448.       ex.printStackTrace();
  449.     }
  450.   }
  451. }