Hi,

I have written a code, when it runs it loads an image and after getting image size it sets the size of the frame in the constructor.

But now i want to load image using FileDialog box and then update the frame size as well. But when i access frame using 'this' keyword the button's ActionListener does not recognize it. What should i do to access the frame attributes?

Thanks.

Dani AI

Generated

Short answer: inside an anonymous ActionListener this refers to the listener object, not the Frame. Use a qualified reference to the outer class (ImgMod8.this) or give the listener a reference to the Frame when you construct it. For image loading, prefer ImageIO.read(File) (returns a BufferedImage with immediate width/height) instead of relying only on asynchronous loading; MediaTracker is fine but more verbose.

Example (minimal, not a copy of your posted code):

loadButton.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) throws IOException {
    FileDialog fd = new FileDialog(ImgMod8.this, "Open Image", FileDialog.LOAD);
    fd.setVisible(true);
    if (fd.getFile() == null) return;
    BufferedImage img = ImageIO.read(new File(fd.getDirectory(), fd.getFile()));
    int w = img.getWidth();
    int h = img.getHeight();
    Insets in = ImgMod8.this.getInsets();
    ImgMod8.this.setSize(in.left + w + 10, in.top + h + 50); // tweak offsets to match your layout
    display.repaint();
  }
});

Troubleshooting notes: if you stay with AWT and Toolkit.getImage() then call MediaTracker.waitForID(...) before getWidth()/getHeight(); otherwise getWidth() can return -1. If you migrate to Swing, use JFrame + JFileChooser + BufferedImage and perform UI changes on the Event Dispatch Thread (SwingUtilities.invokeLater). After resizing, call validate()/repaint() if needed.

As hinted, the core bug is the this reference inside the listener. Options: qualify this with the outer class, pass the Frame into the listener, or make a final field reference. These approaches will let you update the frame size immediately after a user selects an image.

Recommended Answers

All 2 Replies

Well if your ActionListener is an inner class of your frame, then 'this' will point to the ActionListener instead. What's your code look like?

Well if your ActionListener is an inner class of your frame, then 'this' will point to the ActionListener instead. What's your code look like?

class ImgMod8 extends Frame  {
  String msg = "";
  int mX1 = 150;
  int mY1 = 150;
  int mX2 = 0;
  int mY2 = 0; 
  int turn = 1;
  static int dst = 0;
  double sum = 0.0;
  int count;
  Image rawImg;
  int imgCols;//Number of horizontal pixels
  int imgRows;//Number of rows of pixels
  Image modImg;//Reference to modified image
  //Inset values for the Frame
  int inTop;
  int inLeft;
 //To add only one picture at a time
 int ig = 1;
 static String theProcessingClass = "PrintMouse5";
  // This image file will be processed if another file name is
  // not entered on the command line.  
  static String theImgFile = "white.gif";
  MediaTracker tracker;
  Display display = new Display();//A Canvas
  Button replotButton = new Button("Replot");

  //References to arrays that store pixel data.
  int[][][] threeDPix;
  int[][][] threeDPixMod;
  int[] oneDPix;
  //Reference to the image-processing object.
  ImgIntfc04 imageProcessingObject;
  //-------------------------------------------//
  public static void main(String[] args){
    // Program supports gif files and jpg files
    // and possibly some other file types as well.

    //Display name of processing program and
    // image file.
    System.out.println("Processing program: " + theProcessingClass);
    System.out.println("Image file: " + theImgFile);
    //Instantiate an object of this class
    ImgMod8 obj = new ImgMod8();
  }//end main

  //-------------------------------------------//
  public ImgMod8(){//constructor
    //Get an image from the specified file.  Can
    // be in a different directory if the path
    // was entered with the file name on the command line.
    rawImg = Toolkit.getDefaultToolkit().getImage(theImgFile);
    //Use a MediaTracker object to block until
    // the image is loaded or ten seconds has elapsed.
    tracker = new MediaTracker(this);
    tracker.addImage(rawImg,1);
    try{
      if(!tracker.waitForID(1,10000)){
        System.out.println("Load error.");
        System.exit(1);
      }//end if
    }catch(InterruptedException e){
      e.printStackTrace();
      System.exit(1);
    }//end catch
    //Make certain that the file was successfully
    // loaded.
    if((tracker.statusAll(false) & MediaTracker.ERRORED & MediaTracker.ABORTED) != 0){
      System.out.println("Load errored or aborted");
      System.exit(1);
    }//end if
    //Raw image has been loaded.  Get width and
    // height of the raw image.
    imgCols = rawImg.getWidth(this);
    imgRows = rawImg.getHeight(this);
    this.setTitle("Get Pixel Distance");
    this.setBackground(Color.YELLOW);
    this.add(display);
    this.add(replotButton,BorderLayout.SOUTH);
    //Make it possible to get insets and the
    // height of the button.
    setVisible(true);
    //Get and store inset data for the Frame and
    // the height of the button.
    inTop = this.getInsets().top;
    inLeft = this.getInsets().left;
    int buttonHeight = replotButton.getSize().height;
    //Size the frame so that a small amount of
    // yellow background will show on the right
    // and on the bottom when both images are
    // displayed, one above the other.  Also, the
    // placement of the images on the Canvas
    // causes a small amount of background to
    // show between the images.
    this.setSize(inLeft+imgCols + 1,inTop + buttonHeight + imgRows + 7);

    //=========================================//
    //Anonymous inner class listener for replot
    // button.  This actionPerformed method is
    // invoked when the user clicks the Replot
    // button.  It is also invoked at startup
    // when this program posts an ActionEvent to
    // the system event queue attributing the
    // event to the Replot button.
    replotButton.addActionListener(
      new ActionListener(){
        public void actionPerformed(ActionEvent e){
   //Calculate distance
   double a = mX1-mX2;
   double b = mY1-mY2;
   sum=(Math.sqrt(a*a+b*b)) ;
   System.out.println("This Distance is: " + sum);
          //Pass a 3D array of pixel data to the
          // processing object and get a modified 3D array of pixel data back. 
   threeDPixMod = imageProcessingObject.processImg(threeDPix, imgRows, imgCols, mX2, mY2);
          //Convert the modified pixel data to a
          // 1D array of pixel data.
          oneDPix = convertToOneDim(threeDPixMod,imgCols,imgRows);
          //Use the createImage() method to
          // create a new image from the 1D array of pixel data.
          modImg = createImage(new MemoryImageSource(imgCols,imgRows,oneDPix,0,imgCols));
          //Repaint the image display frame with
          // the original image at the top and
          // the modified pixel data at the bottom.
          display.repaint();

        }//end actionPerformed
      }//end ActionListener
    );//end addActionListener
    //End anonymous inner class.
    //=========================================//

I want to add a button named 'Load Image' and load an image from local drive using it. And when the user selects image the frame size should be updated automatically according to size of image.

Regards.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.