Hi!

I'm trying to improve a code shown below. My idea is to add multiple images to JPanel. It sounds like an easy task, but all my attempts failed so far. I tried to create Image image2 = getToolkit().getImage(Drag1.class.getResource("cross_cursor.gif")); and then bi2 = new BufferedImage(image2.getWidth(this), image2.getHeight(this)...); . But I can see only one image on the JPanel. Could anybody help please? Thanks a lot!

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Drag1 extends JFrame {
  DisplayCanvas canvas;

  public Drag1() {
    super();
    Container container = getContentPane();

    canvas = new DisplayCanvas();
    container.add(canvas);

    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    setSize(450, 400);
    setVisible(true);
  }

  public static void main(String arg[]) {
    new Drag1();
  }
}

class DisplayCanvas extends JPanel {
  int x, y;

  BufferedImage bi;

  DisplayCanvas() {
    setBackground(Color.white);
    setSize(450, 400);
    addMouseMotionListener(new MouseMotionHandler());

    Image image = getToolkit().getImage(Drag1.class.getResource("hand_cursor.gif"));

    MediaTracker mt = new MediaTracker(this);
    mt.addImage(image, 1);
    try {
      mt.waitForAll();
    } catch (Exception e) {
      System.out.println("Exception while loading image.");
    }

    if (image.getWidth(this) == -1) {
      System.out.println("no gif file");
      System.exit(0);
    }

    bi = new BufferedImage(image.getWidth(this), image.getHeight(this),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D big = bi.createGraphics();
    big.drawImage(image, 0, 0, this);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D) g;

    g2D.drawImage(bi, x, y, this);
  }

  class MouseMotionHandler extends MouseMotionAdapter {
    public void mouseDragged(MouseEvent e) {
      x = e.getX();
      y = e.getY();
      repaint();
    }
  }
}

Edited 5 Years Ago by LianaN: n/a

Sorry, initially I decided to post a code with 1 image, and to explain in the text my attempts to add more images.

Ok, now I'm posting my full code for 2 images. This code does not work correctly, because I can see only 1 image in JPanel. Please, any help is highly appreciated.

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

public class Drag1 extends JFrame {
  DisplayCanvas canvas;

  public Drag1() {
    super();
    Container container = getContentPane();

    canvas = new DisplayCanvas();
    container.add(canvas);

    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    setSize(450, 400);
    setVisible(true);
  }

  public static void main(String arg[]) {
    new Drag1();
  }
}

class DisplayCanvas extends JPanel {
  int x, y;

  BufferedImage bi; BufferedImage bi2;

  DisplayCanvas() {
    setBackground(Color.white);
    setSize(450, 400);
    addMouseMotionListener(new MouseMotionHandler());

    Image image = getToolkit().getImage(Drag1.class.getResource("hand_cursor.gif"));
    Image image2 = getToolkit().getImage(Drag1.class.getResource("hand_cursor2.gif"));

    MediaTracker mt = new MediaTracker(this);
    mt.addImage(image, 1);
    try {
      mt.waitForAll();
    } catch (Exception e) {
      System.out.println("Exception while loading image.");
    }

    MediaTracker mt2 = new MediaTracker(this);
    mt2.addImage(image2, 1);
    try {
      mt2.waitForAll();
    } catch (Exception e) {
      System.out.println("Exception while loading image.");
    }

    if ((image.getWidth(this) == -1) || (image2.getWidth(this) == -1)) {
      System.out.println("no gif file");
      System.exit(0);
    }

    bi = new BufferedImage(image.getWidth(this), image.getHeight(this),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D big = bi.createGraphics();
    big.drawImage(image, 0, 0, this);

    bi2 = new BufferedImage(image.getWidth(this), image.getHeight(this),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D big2 = bi2.createGraphics();
    big2.drawImage(image2, 50, 50, this);
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D) g;

    g2D.drawImage(bi, x, y, this);
  }

  class MouseMotionHandler extends MouseMotionAdapter {
    public void mouseDragged(MouseEvent e) {
      x = e.getX();
      y = e.getY();
      repaint();
    }
  }
}

Edited 5 Years Ago by LianaN: n/a

paintComponent still only paints the first image
g2D.drawImage(bi, x, y, this);

The draws to big and big2 don't achieve anythig as far as I can see

Edited 5 Years Ago by JamesCherrill: n/a

I changed the paintComponent method:

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2D = (Graphics2D) g;

    g2D.drawImage(bi, x, y, this);

    g2D.drawImage(bi2, x + 50, y + 50, this);
  }

..but still can see only one image... What else could be wrong?

Edited 5 Years Ago by LianaN: n/a

I worked out another piece of code that creates two rectangles. In this case I can drag and drop these two rectangles. But how can I substitute rectangle objects to GIF images?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;

public class Drag1 extends JPanel {
    Rectangle img1 = new Rectangle(100,100,150,75);
    Rectangle img2 = new Rectangle(150,150,200,75);

    boolean draggingIMG1, draggingIMG2 = false;


    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.blue);
        g2.draw(img1);

        g2.setPaint(Color.red);
        g2.draw(img2);
    }

    public void setRect(int x, int y) {
        if(draggingIMG1)
        img1.setLocation(x, y);
        else
        img2.setLocation(x+20, y+20);
        repaint();
    }

    public static void main(String[] args) {
        Drag1 test = new Drag1();
        new GraphicDragController(test);
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(test);
        f.setSize(400,400);
        f.setLocation(100,100);
        f.setVisible(true);
    }
}

class GraphicDragController extends MouseInputAdapter {
    Drag1 component;
    Point offset = new Point();

    public GraphicDragController(Drag1 gdad) {
        component = gdad;
        component.addMouseListener(this);
        component.addMouseMotionListener(this);
    }

    public void mousePressed(MouseEvent e) {
        Point p = e.getPoint();
        Rectangle r;

       if(component.img1.contains(p))
       {
    	   r = component.img1;
	       offset.x = p.x - r.x;
	       offset.y = p.y - r.y;
	       component.draggingIMG1 = true;
       }
       else if(component.img2.contains(p))
       {
    	   r = component.img2;
    	       offset.x = p.x - r.x;
	       offset.y = p.y - r.y;
	       component.draggingIMG2 = true;
       }

    }

    public void mouseReleased(MouseEvent e) {
	component.draggingIMG1 = component.draggingIMG2 = false;
    }

    public void mouseDragged(MouseEvent e) {
       if(component.draggingIMG1) {
           int x = e.getX() - offset.x;
           int y = e.getY() - offset.y;
           component.setRect(x, y);
       }
       else if(component.draggingIMG2) {
           int x = e.getX() - offset.x;
           int y = e.getY() - offset.y;
           component.setRect(x, y);
       }
    }
}

Edited 5 Years Ago by LianaN: n/a

Write new class ie. ImageRectangle extends Rectangle and in single constructor put your BuferredImage and Rectangle parameters

public ImageRectangle(int x, int y, int w, int h, BufferedImage bi) {
            super(x, y, w, h);
            this.bi = bi;
        }

Override Rectangle method

public boolean contains(Point p)

write own method

public void drawImage(Graphics2D g2)

Image is a rectangle, x,y,width,height are just common.

Thank you very much! I updated my code based on your comments.

class ImageRectangle extends Rectangle {
         int a, b, c, d;
         BufferedImage bi;
         
         public ImageRectangle (int x, int y, int w, int h, BufferedImage bi) {
            super(x, y, w, h);
            this.a = x; this.b = y; this.c = w; this.d = h;
            this.bi = bi;
         }
         
         @Override
         public boolean contains(Point p) {
             return ((a <= x && x <= (a + c)) && (b <= y && y <= (b + d)));
         }
                    
         //public void drawImage(Graphics2D g2) {
         //   g2.draw(this);
         //} 
    }

But I still have problems with drawImage. Could you please help me to finish it or just give some links?

Edited 5 Years Ago by LianaN: n/a

I just posted a new reply, but I see that you already answered. So, let me try your proposal.

Edited 5 Years Ago by LianaN: n/a

line 2,7 delete them, you have direct access to x, y, w, h, (extends Rectangle!)
Rectangle have a method contains(Point p)
In place of 13 write return super.contains(p)

public void drawImage(Graphics2D g2) {
            g2.drawImage(bi, x, y, null);
        }

Invoke this method for two images in Drag1 paintComponent(...) method

protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        img1.drawImage(g2);
        img2.drawImage(g2);
    }

//

class GraphicDragController extends MouseInputAdapter {

    Drag2 component;

    public GraphicDragController(Drag2 gdad) {
        component = gdad;
        component.addMouseListener(this);
        component.addMouseMotionListener(this);
    }

    public void mousePressed(MouseEvent e) {
        Point p = e.getPoint();
        component.img1.mousePressed(p);
        component.img2.mousePressed(p);
        component.repaint();
    }

    public void mouseReleased(MouseEvent e) {
        component.img1.mouseReleased();
        component.img2.mouseReleased();
        component.repaint();
    }

    public void mouseDragged(MouseEvent e) {
        Point p = e.getPoint();
        component.img1.mouseDragged(p);
        component.img2.mouseDragged(p);
        component.repaint();
    }
}

Class ImageRectangle should handle mouse events

Loading images put to the constructor

ImageRectangle img1;
    ImageRectangle img2;

    public Drag1() {
        try {
            Image image1 = ImageIO.read(getClass().getResource("ScanImage30.jpg"));
            BufferedImage bi1 = new BufferedImage(image1.getWidth(this), image1.getHeight(this),
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D big = bi1.createGraphics();
            big.drawImage(image1, 0, 0, this);
            img1 = new ImageRectangle("alfa", 10, 100, bi1.getWidth(), bi1.getHeight(), bi1);

            Image image2 = ImageIO.read(getClass().getResource("y00000001.jpg"));
            BufferedImage bi2 = new BufferedImage(image2.getWidth(this), image2.getHeight(this),
                    BufferedImage.TYPE_INT_ARGB);
            Graphics2D big2 = bi2.createGraphics();
            big2.drawImage(image2, 0, 0, this);
            img2 = new ImageRectangle("beta", 100, 100, bi2.getWidth(), bi2.getHeight(), bi2);
        } catch (IOException ex) {
            //
        }
    }

Edited 5 Years Ago by quuba: public Drag1() lines 11 ,18 changed

Thank you very much! I suppose that the problem is almost solved. So,images can be dragged and dropped, but they:
1) move together;
2) move only along a diagonal.

I guess that IF...THEN should be added to GraphicDragController in order to check an image to be moved. But which "if condition" is better to use? Should I use some boolean variable?

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.MouseInputAdapter;

public class Drag1 extends JPanel {
    ImageRectangle img1;
    ImageRectangle img2;

    boolean draggingIMG1, draggingIMG2 = false;

    public Drag1() {
        try {
            Image image1 = ImageIO.read(getClass().getResource("hand_cursor.gif"));
            BufferedImage bi1 = new BufferedImage(image1.getWidth(this), image1.getHeight(this),
            BufferedImage.TYPE_INT_ARGB);
            Graphics2D big = bi1.createGraphics();
            big.drawImage(image1, 0, 0, this);
            img1 = new ImageRectangle(10, 100, bi1.getWidth(), bi1.getHeight(), bi1);

            Image image2 = ImageIO.read(getClass().getResource("hand_cursor.gif"));
            BufferedImage bi2 = new BufferedImage(image2.getWidth(this), image2.getHeight(this),
            BufferedImage.TYPE_INT_ARGB);
            Graphics2D big2 = bi2.createGraphics();
            big2.drawImage(image2, 0, 0, this);
            img2 = new ImageRectangle(100, 100, bi1.getWidth(), bi1.getHeight(), bi2);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
        img1.drawImage(g2);
        img2.drawImage(g2);
    }

    public static void main(String[] args) {
        Drag1 test = new Drag1();
        new GraphicDragController(test);
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(test);
        f.setSize(400,400);
        f.setLocation(100,100);
        f.setVisible(true);
    }
}

    class GraphicDragController extends MouseInputAdapter {
      Drag1 component;

      public GraphicDragController(Drag1 gdad) {
          component = gdad;
          component.addMouseListener(this);
          component.addMouseMotionListener(this);
      }

      public void mousePressed(MouseEvent e) {
      Point p = e.getPoint();
          component.img1.mousePressed(p);
          component.img2.mousePressed(p);
          component.repaint();
      }

      public void mouseReleased(MouseEvent e) {
          component.img1.mouseReleased();
          component.img2.mouseReleased();
          component.repaint();
      }

      public void mouseDragged(MouseEvent e) {
          Point p = e.getPoint();
          component.img1.mouseDragged(p);
          component.img2.mouseDragged(p);
          component.repaint();
      }
    }

    class ImageRectangle extends Rectangle {
         BufferedImage bi;
         Point offset = new Point();

         public ImageRectangle (int x, int y, int w, int h, BufferedImage bi) {
            super(x, y, w, h);
            this.bi = bi;
         }

         @Override
         public boolean contains(Point p) {
             return super.contains(p);
         }

         public void drawImage(Graphics2D g2) {
             g2.drawImage(bi, x, y, null);
         }

         void mouseDragged(Point p) {
            x = p.y - offset.x;
            y = p.y - offset.y;;
         }

         void mouseReleased() {

         }

         void mousePressed(Point p) {
            offset.x = p.x - x;
            offset.y = p.y - y;
         }
    }

Edited 5 Years Ago by LianaN: n/a

As usual, page 2 is shown, but I have not noticed this.

I guess that IF...THEN should be added to GraphicDragController in order to check an image to be moved.

So, too quickly I removed this option (usefull)
Line 107 fault

Edited 5 Years Ago by quuba: n/a

This question has already been answered. Start a new discussion instead.