Search code examples
javaswingpaintcomponentrepaint

What should I have in paintComponent to drag and rotate an image?


I have worked with the school assignment for quite some time now. But I can not really understand what I should do. The assignment is due tomorrow and I feel quite stressed.

The task is, I'll get some pictures, have them in a window, then be able to move around them and also be able to rotate.

The big problem is that I do not know how I'll manage paintComponent(). What I read is that it should be called automatic "when needed" and when you call repaint(). I find it hard to get it to work.

The main class

import java.awt.*;
import javax.swing.*;
import java.util.*;

public class JFrameC extends JFrame{

JPanel panel;
ArrayList <ThePhoto> oneArray = new  <ThePhoto> ArrayList();

   public JFrameC(){
       super("This window");

       setLayout(new BorderLayout());

       panel = new JPanel();
       panel.setBackground(Color.GREEN);
       panel.setLayout(null);

       add(panel);

       setSize(500,500);
       setVisible(true);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
   }

   public void addPicture(String name){

       oneArray.add(new ThePhoto(name, this));
       panel.add(oneArray.get(oneArray.size()-1).getJPanel());

   }    

   public void draw(JPanel p){


//One of the tasks is that the image is pressed to end up on top.
//I thought that if I sort of an ArrayList so I can keep track of which one
//is on top. Then be able to paint them in order.

       for(ThePhoto x : oneArray){

           if(x.getJPanel() == p && oneArray.indexOf(x) != 0){

               int i = oneArray.indexOf(x);

               for(;i > 0; i--){
                   ThePhoto temp = oneArray.get(i);
                   oneArray.set(i, oneArray.get(i-1));
                   oneArray.set(i-1, temp);
               }
               break;
           }
       }

       panel.validate();//I can not get this to work
       panel.repaint();             

       getContentPane().validate();//Or this.
       getContentPane().repaint();          
   }

   public void paintComponent(Graphics g){  
       //Is this right?
       //What should I write here?
   }

   public static void main(String[] args) {

       JFrameC j = new JFrameC();

       j.addPicture("one.gif");
       j.addPicture("two.gif");
       j.addPicture("three.gif");
       j.addPicture("four.gif");
   }
}

Class

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

public class ThePhoto{

   ImageIcon onePicture;
   JLabel l;
   JPanel p;
   JFrameC k;
   int posX = 10;
   int posY = 10;

   public ThePhoto(String name, JFrameC k){

       this.k = k;

       onePicture = new ImageIcon(name);

       l = new JLabel(onePicture);

       p = new JPanel();
       p.setLayout(new CardLayout());
       p.setBorder(null);
       p.setBackground(null);
       p.add(l);

       p.setBounds(posX, posY, 100, 100);
       p.addMouseListener(new HandleMouse(k, this));
       p.addMouseMotionListener(new HandleMouse(k, this));
   }

   public void setX(int x){posX = x;}
   public void setY(int y){posY = y;}
   public JPanel getJPanel(){return p;}

   public void paintComponent(Graphics g){  

           //Is this right?
           //What should I write here?

    }
}

MouseEvent Class

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.*;
import javax.swing.*;

public class HandleMouse extends MouseAdapter implements MouseMotionListener{

       JFrame k;
   ThePhoto b;

   public HandleMouse(JFrameC k, ThePhoto b){

       this.k = k;
       this.b = b;
   }

   public void mouseClicked (MouseEvent e) {

       k.draw((JPanel)e.getComponent());    
   }

   public void mouseDragged (MouseEvent e) {

       e.translatePoint(e.getComponent().getLocation().x, e.getComponent().getLocation().y);
       e.getComponent().setLocation(e.getX(), e.getY());

       b.setX(e.getX());
       b.setY(e.getY());

   }

   public void mouseReleased(MouseEvent e) {

       k.draw((JPanel)e.getComponent());
       }
}

To summarize the issues clearer:

1.Is it best to call repaint() to Frame or Panel? As, I understand it is in both cases everything 'in' the container that will be repainted. And if so, should JFrame be preferable?

2.Is there any routine/usual/rule on what should be in the paintComponent()?

3.What advice and criticism whatsoever is very welcome. But please write so that a beginner understands and no unnecessary insults.

I understand that nobody wants to do my homework. But I only ask for some advice so that I can get better. I also want to write that I am a novice and therefore looks like my code to be written by a novice.


Solution

  • Solve the problem for a single image before trying for multiple images. Starting from this example, use ImageIO.read() to initialize an image and use drawImage() to render it in paintComponent().

    private final BufferedImage image = getImage();
    private BufferedImage getImage() {
        try {
            return ImageIO.read(new URL(
                "http://i.imgur.com/kxXhIH1.jpg"));
        } catch (IOException e) {
            e.printStackTrace(System.err);
        }
        return null;
    }
    …
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image,
            textPt.x - image.getWidth() / 2,
            textPt.y - image.getHeight() / 2, this);
    }
    

    You can rotate the graphics context as shown here.

    image