package viewer.hoese; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.awt.geom.*; import java.io.File; import java.awt.image.BufferedImage; import sj.lang.ListExpr; import tools.Base64Encoder; import tools.Base64Decoder; import java.io.*; import tools.Reporter; /** * This class handles a image object together with an * rectangle describing, where the position of this * image is in worldcoordinates. **/ public class ImageBackgroundDialog extends JDialog{ /** Construct this */ public ImageBackgroundDialog(Frame owner){ // create the dialog super(owner,true); useColorCB = new JCheckBox("use Color"); selectedColorLabel = new JLabel(" color "); selectedColorLabel.setOpaque(true); selectedColorLabel.setBackground(Color.WHITE); JButton chooseColorBtn = new JButton("choose color"); chooseColorBtn.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent evt){ Color c = JColorChooser.showDialog(null, "Select a color", selectedColorLabel.getBackground()); if(c!=null){ selectedColorLabel.setBackground(c); } } }); JPanel colorPanel = new JPanel(); colorPanel.add(new JLabel ("BackgroundColor:")); colorPanel.add(useColorCB); colorPanel.add(selectedColorLabel); colorPanel.add(chooseColorBtn); JPanel P = new JPanel(new GridLayout(8,2)); P.add(new JLabel("x",JLabel.RIGHT)); P.add(XTF = new JTextField(6)); P.add(new JLabel("y",JLabel.RIGHT)); P.add(YTF = new JTextField(6)); P.add(new JLabel("width",JLabel.RIGHT)); P.add(WTF = new JTextField(6)); P.add(new JLabel("height",JLabel.RIGHT)); P.add(HTF = new JTextField(6)); P.add(new JLabel("")); useForBBox.setSelected(false); P.add(useForBBox); useTFW.setSelected(false); P.add(useTFW); P.add(loadTFW); P.add(SelectImageBtn = new JButton("select Image")); P.add(RemoveImageBtn = new JButton("remove Image")); P.add(ImageName = new JLabel("")); getContentPane().setLayout(new BorderLayout()); JPanel P2 = new JPanel(new GridLayout(2,1)); JPanel P4 = new JPanel(); P4.add(P); P2.add(P4); imageDisplay = new ImageDisplay(); JPanel P5 = new JPanel(new BorderLayout()); P5.add(imageDisplay,BorderLayout.CENTER); P5.add(pixX,BorderLayout.SOUTH); P5.add(pixY,BorderLayout.WEST); P2.add(P5); getContentPane().add(P2,BorderLayout.CENTER); JPanel CP = new JPanel(new GridLayout(2,2)); CP.add(ApplyBtn = new JButton("Apply")); CP.add(ResetBtn = new JButton("Reset")); CP.add(OkBtn = new JButton("Ok")); CP.add(CancelBtn = new JButton("Cancel")); getContentPane().add(CP,BorderLayout.SOUTH); getContentPane().add(colorPanel, BorderLayout.NORTH); // assign methods to the buttons ActionListener AL = new ActionListener(){ public void actionPerformed(ActionEvent evt){ Object s = evt.getSource(); if(s==null) return; if(s.equals(SelectImageBtn)) selectImage(); else if(s.equals(RemoveImageBtn)) removeImage(); else if(s.equals(ApplyBtn)) apply(); else if(s.equals(ResetBtn)) reset(); else if(s.equals(OkBtn)){ if(apply()) setVisible(false); } else if(s.equals(CancelBtn)){ reset(); setVisible(false); } } }; ApplyBtn.addActionListener(AL); CancelBtn.addActionListener(AL); ResetBtn.addActionListener(AL); SelectImageBtn.addActionListener(AL); RemoveImageBtn.addActionListener(AL); OkBtn.addActionListener(AL); loadTFW.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent evt){ if(!tfw.load()){ Reporter.showError("Error in loading file"); } } }); useTFW.addChangeListener(new javax.swing.event.ChangeListener(){ public void stateChanged(javax.swing.event.ChangeEvent evt){ if(useTFW.isSelected()){ if(!tfw.initialized){ useTFW.setSelected(false); Reporter.showError("load tfw file first"); return; } XTF.setEnabled(false); YTF.setEnabled(false); WTF.setEnabled(false); HTF.setEnabled(false); R1.setRect(0,0,100,100); if(theImage!=null){ R1.setRect(theImage.getMinX(),theImage.getMinY(),theImage.getWidth(),theImage.getHeight()); } tfw.convertRectangle(R1,R2); double w= Math.max(1,R2.getWidth()); double h = Math.max(1,R2.getHeight()); bounds.setRect(R2.getX(),R2.getY(),w,h); reset(); } else{ XTF.setEnabled(true); YTF.setEnabled(true); WTF.setEnabled(true); HTF.setEnabled(true); } } }); setSize(640,480); reset();// put the initail values into the textfields } private void selectImage(){ if(FC.showOpenDialog(this)==JFileChooser.APPROVE_OPTION){ File f = FC.getSelectedFile(); try{ BufferedImage img = javax.imageio.ImageIO.read(f); if(img==null){ Reporter.showError("Error in creating image from file"); return; } theImage = img; imageDisplay.setImage(theImage); ImageName.setText(f.getName()); } catch(Exception e){ Reporter.showError("Error in creating image from file"); } } } private void removeImage(){ theImage = null; imageDisplay.setImage(theImage); ImageName.setText(""); } private boolean apply(){ double tmpx,tmpy,tmpw,tmph; try{ tmpx = Double.parseDouble(XTF.getText()); tmpy = Double.parseDouble(YTF.getText()); tmpw = Double.parseDouble(WTF.getText()); tmph = Double.parseDouble(HTF.getText()); }catch(Exception e){ Reporter.showError("All entries have to be real numbers. "); return false; } if(tmpw<=0 || tmph <=0){ Reporter.showError("width and height have to be greater than zero. "); return false; } bounds.setRect(tmpx,tmpy,tmpw,tmph); return true; } private void reset(){ XTF.setText(""+bounds.getX()); YTF.setText(""+bounds.getY()); WTF.setText(""+bounds.getWidth()); HTF.setText(""+bounds.getHeight()); } public void setImage(BufferedImage img){ theImage = img; imageDisplay.setImage(theImage); if(img==null) ImageName.setText(""); else ImageName.setText("internal"); } public boolean setBBox(double x, double y, double w, double h){ if(w<=0 || h<=0) return false; bounds.setRect(x,y,w,h); reset(); // put the values into the textfields return true; } public boolean setBBox(Rectangle2D.Double r){ if(r==null || r.getHeight()<=0 || r.getWidth()<=0){ return false; } bounds = r; reset(); return true; } public boolean useForBoundingBox(){ return useForBBox.isSelected(); } /** * Returns the image of this ImageBackgroundDialog * If no image is available, the result will be null. */ public BufferedImage getImage(){ return theImage; } /** * returns the bounding box of this Image */ public Rectangle2D.Double getBBox(){ return bounds; } /** Returns the nested list representation of this ImageBackgroundDialog */ public ListExpr toListExpr(String BackgroundImagePath){ ListExpr ImageList; if(theImage==null){ ImageList = ListExpr.theEmptyList(); }else{ try{ // select a non-existent fileName for the image File F = new File(BackgroundImagePath); if(!F.exists()){ Reporter.showError("Error in creating background image \n"+ " directory "+BackgroundImagePath + "don't exists"); ImageList = ListExpr.theEmptyList(); } else if(!F.isDirectory()){ Reporter.showError("Error in creating background image \n"+ BackgroundImagePath + "is not a directory"); ImageList = ListExpr.theEmptyList(); } else{ if(!BackgroundImagePath.endsWith(File.separator)) BackgroundImagePath+=File.separator; String FileName = ".background"; int BGNumber = -1; do{ BGNumber++; F = new File(BackgroundImagePath+FileName+BGNumber+".png"); }while(F.exists()); javax.imageio.ImageIO.write(theImage,"png",F); ImageList = ListExpr.textAtom(FileName+BGNumber+".png"); } }catch(Exception e){ Reporter.showError("cannot create the ListExpr for Background Image "); Reporter.debug(e); ImageList=ListExpr.theEmptyList(); } } return ListExpr.fiveElemList( ListExpr.realAtom(bounds.getX()), ListExpr.realAtom(bounds.getY()), ListExpr.realAtom(bounds.getWidth()), ListExpr.realAtom(bounds.getHeight()), ImageList); } /** Reads the values from this component from a ListExpr **/ public boolean readFromListExpr(ListExpr le,String BackgroundImagePath){ if(le.listLength()!=5) return false; if(le.first().atomType()!=ListExpr.REAL_ATOM || le.second().atomType()!=ListExpr.REAL_ATOM || le.third().atomType()!=ListExpr.REAL_ATOM || le.fourth().atomType()!=ListExpr.REAL_ATOM) return false; ListExpr ImageList = le.fifth(); BufferedImage bi=null; if(ImageList.atomType()==ListExpr.NO_ATOM){ if(!ImageList.isEmpty()) return false; }else{ if(ImageList.atomType()!=ListExpr.TEXT_ATOM) return false; // try to restore the background from given file if(!BackgroundImagePath.endsWith(File.separator)) BackgroundImagePath+=File.separator; File F = new File(BackgroundImagePath+le.fifth().textValue()); if(!F.exists()){ Reporter.showError("Background File not found"); bi = null;; } else{ // ok file exists-> read the image try{ bi = javax.imageio.ImageIO.read(F); }catch(Exception e){ Reporter.showError("Error in loading background-Image"); bi=null; } } } if(!setBBox(le.first().realValue(),le.second().realValue(), le.third().realValue(),le.fourth().realValue())){ return false; } setImage(bi); reset(); return true; } /** returns the selected backgroundcolor **/ public Color getBackgroundColor(){ if(useColorCB.isSelected()){ return selectedColorLabel.getBackground(); } else { return null; } } /** reads the contents of all fields from a ImageBackground **/ public void readFrom(ImageBackground ibg){ setImage(ibg.getImage()); setBBox(ibg.getBBox()); Color c = ibg.getBackgroundColor(); if(c!=null){ useColorCB.setSelected(true); selectedColorLabel.setBackground(c); } else { useColorCB.setSelected(false); } } private BufferedImage theImage=null; private ImageDisplay imageDisplay; private Rectangle2D.Double bounds = new Rectangle2D.Double(0,0,10,10); private JTextField XTF; private JTextField YTF; private JTextField WTF; private JTextField HTF; private JRadioButton useTFW = new JRadioButton("use tfw"); private JButton loadTFW = new JButton("loadTFW"); private JButton SelectImageBtn; private JButton RemoveImageBtn; private JLabel ImageName; private JButton ResetBtn; private JButton ApplyBtn; private JButton OkBtn; private JButton CancelBtn; private JLabel pixX = new JLabel("width= ",JLabel.CENTER); private JLabel pixY = new JLabel("height= "); private JFileChooser FC = new JFileChooser(); private TFW tfw = new TFW(); private Rectangle2D.Double R1 = new Rectangle2D.Double(); private Rectangle2D.Double R2 = new Rectangle2D.Double(); private JRadioButton useForBBox = new JRadioButton("include in bbox"); private JLabel selectedColorLabel; private JCheckBox useColorCB; private class TFW{ String filename=""; double pixXSize=1.0; double pixYSize=1.0; double transX=0.0; double transY=0.0; double rotX=0.0; double rotY=0.0; boolean initialized = false; void convertRectangle(Rectangle2D.Double source,Rectangle2D.Double result){ double xs1 = source.getX(); double ys1 = source.getY(); double xs2 = xs1+source.getWidth(); double ys2 = ys1+source.getHeight(); double xr1 = pixXSize*xs1+rotX*ys1+transX; double xr2 = pixXSize*xs2+rotX*ys2+transX; double yr1 = pixYSize*ys1+rotY*xs1+transY; double yr2 = pixYSize*ys2+rotY*xs2+transY; double tmp; if(yr1>yr2){ tmp = yr1; yr1 = yr2; yr2 = tmp; } result.setRect(xr1,yr1,xr2-xr1,yr2-yr1); } boolean load(){ if(FC.showOpenDialog(null)==JFileChooser.APPROVE_OPTION){ File file = FC.getSelectedFile(); try{ BufferedReader BR = new BufferedReader(new InputStreamReader(new FileInputStream(file))); String line; double tmpXSize=0,tmpYSize=0,tmpRotX=0,tmpRotY=0,tmpTransX=0,tmpTransY=0; line = BR.readLine(); if(line==null) return false; line = line.trim().trim(); // remove " *" tmpXSize=Double.parseDouble(line); line = BR.readLine(); if(line==null) return false; line = line.trim(); // remove " *" tmpRotX=Double.parseDouble(line); line = BR.readLine(); if(line==null) return false; line = line.trim(); // remove " *" tmpRotY=Double.parseDouble(line); line = BR.readLine(); if(line==null) return false; line = line.trim(); // remove " *" tmpYSize=Double.parseDouble(line); line = BR.readLine(); if(line==null) return false; line = line.trim(); // remove " *" tmpTransX=Double.parseDouble(line); line = BR.readLine(); if(line==null) return false; line = line.trim(); // remove " *" tmpTransY=Double.parseDouble(line); BR.close(); if(tmpXSize<=0) return false; if(tmpYSize==0) return false; pixXSize = tmpXSize; pixYSize = tmpYSize; rotX = tmpRotX; rotY = tmpRotY; transX = tmpTransX; transY = tmpTransY; filename = file.getAbsolutePath(); initialized=true; return true; }catch(Exception e){ Reporter.debug(e); return false; } } else{ return true; // abort is not an error } } } private class ImageDisplay extends JLabel implements java.awt.image.ImageObserver{ public ImageDisplay(){} public ImageDisplay(String str){super(str);} public void paint(Graphics g){ super.paint(g); if(theImage!=null){ Rectangle2D bounds = getBounds(); int w = theImage.getWidth(this); int h= theImage.getHeight(this); double sf = Math.min(bounds.getWidth()/w,bounds.getHeight()/h); int w1 = (int) (sf*w); int h1 = (int) (sf*h); int x = (int) ((bounds.getWidth()-w1) /2); int y = (int) ((bounds.getHeight()-h1) /2); g.drawImage(theImage,x,y,w1,h1,this); } } /** Function for implementing the imageobserver interface */ public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { if((infoflags & ALLBITS) >0){ if(useTFW.isSelected()){ R1.setRect(x,y,width,height); tfw.convertRectangle(R1,R2); double w= Math.max(1,R2.getWidth()); double h = Math.max(1,R2.getHeight()); bounds.setRect(R2.getX(),R2.getY(),w,h); reset(); } pixX.setText("width = "+(width)); pixY.setText("height = "+(height)); repaint(); return false; } return true; } public void setImage(BufferedImage img){ theImage = img; if(useTFW.isSelected()&&img!=null){ R1.setRect(img.getMinX(),img.getMinY(),img.getWidth(),img.getHeight()); tfw.convertRectangle(R1,R2); double w= Math.max(1,R2.getWidth()); double h = Math.max(1,R2.getHeight()); bounds.setRect(R2.getX(),R2.getY(),w,h); reset(); } if(img!=null){ pixX.setText("width = "+img.getWidth()); pixY.setText("height = "+img.getHeight()); }else{ pixX.setText("width = "); pixY.setText("height = "); } repaint(); } private Image theImage; } }