Subversion Repositories wimsdev

Rev

Rev 3662 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     Sketch Elements: Chemistry molecular diagram drawing tool.
  3.    
  4.     (c) 2005 Dr. Alex M. Clark
  5.    
  6.     Released as GNUware, under the Gnu Public License (GPL)
  7.    
  8.     See www.gnu.org for details.
  9. */
  10.  
  11. package WIMSchem;
  12.  
  13. import java.util.*;
  14. import java.io.*;
  15. import java.awt.*;
  16. import java.awt.event.*;
  17. import java.awt.image.*;
  18. import javax.swing.*;
  19.  
  20. /*
  21.     A window class for displaying a catalog of structures, ripped out of a text-style database such as an SD-file.
  22. */
  23.  
  24. public class CatalogWindow extends JFrame
  25.     implements MolSelectListener, ActionListener, ComponentListener, AdjustmentListener, WindowListener
  26. {
  27.     String catFN;
  28.     FileInputStream istr=null;
  29.  
  30.     final int COL_SIZE=5;
  31.     int basepos=0,selnum=-1,highestUpdated=0;
  32.  
  33.     Color bckgr,highl;
  34.  
  35.     JScrollBar scroll;
  36.     JButton bopen,bclose;
  37.     EditorPane[] entries;
  38.    
  39.     CatalogLoader loader=null;
  40.  
  41.     public CatalogWindow(String CatFN)
  42.     {
  43.         catFN=CatFN;
  44.        
  45.         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  46.         JFrame.setDefaultLookAndFeelDecorated(false);
  47.        
  48.         setTitle("WIMSchem Catalog - "+catFN);
  49.  
  50.         bckgr=getBackground();
  51.         highl=new Color(Math.max(bckgr.getRed()-32,0),Math.max(bckgr.getGreen()-32,0),bckgr.getBlue());
  52.  
  53.         ImageIcon mainIcon=new ImageIcon(getClass().getResource("/images/MainIcon.png"));
  54.         setIconImage(mainIcon.getImage());
  55.  
  56.         GridBagLayout gb=new GridBagLayout();
  57.         GridBagConstraints gc=new GridBagConstraints();
  58.         gc.insets=new Insets(2,2,2,2);
  59.        
  60.         // add the molecules
  61.         JPanel content=new JPanel();
  62.         content.setLayout(new BoxLayout(content,BoxLayout.X_AXIS));
  63.         entries=new EditorPane[COL_SIZE];
  64.         for (int n=0;n<COL_SIZE;n++)
  65.         {
  66.             entries[n]=new EditorPane(100,100);
  67.             entries[n].setEditable(false);
  68.             entries[n].setMolSelectListener(this);
  69.             entries[n].setToolCursor();
  70.             entries[n].setBorder(true);
  71.             entries[n].setMaximumSize(new Dimension(Short.MAX_VALUE,Short.MAX_VALUE));
  72.             content.add(entries[n]);
  73.         }
  74.         gc.fill=GridBagConstraints.BOTH;
  75.         gc.gridwidth=GridBagConstraints.REMAINDER;
  76.         gc.weightx=1;
  77.         gc.weighty=1;
  78.         gb.setConstraints(content,gc);
  79.         add(content);
  80.        
  81.         // add the scroller and buttons
  82.         gc.fill=GridBagConstraints.HORIZONTAL;
  83.         gc.weighty=0;
  84.  
  85.         scroll=new JScrollBar(JScrollBar.HORIZONTAL,0,0,0,0);
  86.         scroll.addAdjustmentListener(this);
  87.         gc.gridwidth=5;
  88.         gc.weightx=1;
  89.         gb.setConstraints(scroll,gc);
  90.         add(scroll);
  91.        
  92.         bopen=new JButton("Open");
  93.         bopen.addActionListener(this);
  94.         bopen.setMnemonic(KeyEvent.VK_O);
  95.         gc.gridwidth=1;
  96.         gc.weightx=0;
  97.         gb.setConstraints(bopen,gc);
  98.         add(bopen);
  99.        
  100.         bclose=new JButton("Close");
  101.         bclose.setMnemonic(KeyEvent.VK_C);
  102.         bclose.addActionListener(this);
  103.         gc.gridwidth=1;
  104.         gc.weightx=0;
  105.         gb.setConstraints(bclose,gc);
  106.         add(bclose);
  107.  
  108.         setLayout(gb);
  109.         pack();
  110.         addComponentListener(this);
  111.         addWindowListener(this);
  112.  
  113.         try
  114.         {      
  115.             istr=new FileInputStream(catFN);
  116.         }
  117.         catch (IOException e)
  118.         {
  119.             JOptionPane.showMessageDialog(null,e.toString(),"Catalog Read Failed",JOptionPane.ERROR_MESSAGE);
  120.             dispose();
  121.             return;
  122.         }
  123.  
  124.         loader=new CatalogLoader(this,istr);
  125.         loader.start();
  126.     }
  127.    
  128.    
  129.     public void synch(int Sz)
  130.     {
  131.         scroll.setMaximum(Sz);
  132.         scroll.setVisibleAmount(COL_SIZE);
  133.         scroll.setUnitIncrement(1);
  134.         scroll.setBlockIncrement(COL_SIZE);
  135.        
  136.         if (basepos+5>=Sz || highestUpdated<=COL_SIZE) updatePosition(basepos);
  137.         highestUpdated=Sz;
  138.     }
  139.  
  140.     private void updatePosition(int NewPos)
  141.     {
  142.         // NB: should speed this up sometime by re-using molecules that are already loaded
  143.    
  144.         basepos=NewPos;
  145.         try
  146.         {
  147.             for (int n=0;n<COL_SIZE;n++)
  148.             {
  149.                 if (basepos+n>=loader.count())
  150.                 {
  151.                     entries[n].setBackground(bckgr);
  152.                     entries[n].clear();
  153.                 }
  154.                 else
  155.                 {
  156.                     Molecule mol=loader.get(basepos+n);
  157.                     entries[n].setBackground(basepos+n==selnum ? highl : bckgr);
  158.                     entries[n].replace(mol,true,false);
  159.                     entries[n].scaleToFit();
  160.                     entries[n].repaint();
  161.                 }
  162.             }
  163.         }
  164.         catch (Exception e) {e.printStackTrace();}
  165.     }
  166.  
  167.     private synchronized void openMolecule(int N)
  168.     {
  169.         try
  170.         {
  171.             Molecule mol=loader.get(N);
  172.             MainWindow mw=new MainWindow(null,false);
  173.             mw.mainPanel().setMolecule(mol);
  174.             mw.setVisible(true);
  175.         }
  176.         catch (Exception e) {e.printStackTrace();}
  177.     }
  178.  
  179.     // event handling
  180.  
  181.     public void molSelected(EditorPane source,int idx,boolean dblclick)
  182.     {
  183.         int entnum=-1;
  184.         for (int n=0;n<COL_SIZE;n++) if (source==entries[n]) {entnum=n; break;}
  185.         if (entnum>=0)
  186.         {
  187.             selnum=basepos+entnum;
  188.             for (int n=0;n<COL_SIZE;n++)
  189.             {
  190.                 entries[n].setBackground(n==entnum ? highl : bckgr);
  191.                 entries[n].repaint();
  192.             }
  193.            
  194.             if (idx!=0) openMolecule(selnum);
  195.         }
  196.        
  197.     }
  198.     public void dirtyChanged(boolean isdirty) {}
  199.    
  200.     public void actionPerformed(ActionEvent e)
  201.     {
  202.         if (e.getSource()==bopen) {if (selnum>=0) openMolecule(selnum);}
  203.         if (e.getSource()==bclose)
  204.         {
  205.             if (loader!=null) loader.zap();
  206.             dispose();
  207.             return;
  208.         }
  209.     }
  210.  
  211.     public void componentHidden(ComponentEvent e) {}
  212.     public void componentMoved(ComponentEvent e) {}
  213.     public void componentResized(ComponentEvent e)
  214.     {
  215.         for (int n=0;n<COL_SIZE;n++) entries[n].scaleToFit();
  216.     }
  217.     public void componentShown(ComponentEvent e) {}
  218.  
  219.     public void adjustmentValueChanged(AdjustmentEvent e)
  220.     {
  221.         if (e.getSource()==scroll)
  222.         {
  223.             int pos=e.getValue();
  224.             if (pos!=basepos) updatePosition(pos);
  225.         }
  226.     }
  227.    
  228.     public void windowActivated(WindowEvent e) {}
  229.     public void windowClosed(WindowEvent e) {loader.zap();}
  230.     public void windowClosing(WindowEvent e) {}
  231.     public void windowDeactivated(WindowEvent e) {}
  232.     public void windowDeiconified(WindowEvent e) {}
  233.     public void windowIconified(WindowEvent e) {}
  234.     public void windowOpened(WindowEvent e) {}
  235. }
  236.  
  237. // background thread which loads up the entries of the database, and lets the window know when new ones have arrived
  238.  
  239. class CatalogLoader extends Thread
  240. {
  241.     CatalogWindow wnd;
  242.     FileInputStream istr;
  243.     boolean zap=false;
  244.     ArrayList<Long> filepos=new ArrayList<Long>();
  245.     Object mutex=new Object();
  246.  
  247.     public CatalogLoader(CatalogWindow Wnd,FileInputStream IStr)
  248.     {
  249.         wnd=Wnd;
  250.         istr=IStr;
  251.     }
  252.    
  253.     public void run()
  254.     {
  255.         try
  256.         {          
  257.             long pos=0,nextpos;
  258.             while (!zap)
  259.             {
  260.                 synchronized (mutex) {nextpos=MoleculeStream.findNextPosition(istr,pos);}
  261.                 if (nextpos<0) break;
  262.  
  263.                 filepos.add(pos);
  264.                 pos=nextpos;
  265.                
  266.                 // inform the main window that is has work to do!
  267.                 EventQueue.invokeLater(new Runnable()
  268.                 {
  269.                     public void run()
  270.                     {
  271.                         wnd.synch(filepos.size());
  272.                     }
  273.                 });
  274.             }
  275.         }
  276.         catch (IOException e)
  277.         {
  278.             JOptionPane.showMessageDialog(null,e.toString(),"Catalog Load Failed",JOptionPane.ERROR_MESSAGE);
  279.             e.printStackTrace();
  280.         }
  281.     }
  282.    
  283.     public void zap() {zap=true;}
  284.     public int count() {synchronized(mutex) {return filepos.size();}}
  285.     public Molecule get(int N)
  286.     {
  287.         try
  288.         {
  289.             synchronized(mutex) {return MoleculeStream.fetchFromPosition(istr,filepos.get(N).longValue());}
  290.         }
  291.         catch (IOException e) {return null;}
  292.     }
  293. }
  294.