0

My application can crop images. What I want to achieve is rectangle to be drawn before image is cut according to the coordinates taken from the MouseListeners. This is my code:

public class ImageScreenShot extends JPanel implements MouseListener, MouseMotionListener {

    ImagePanel im;

    int drag_status = 0, c1, c2, c3, c4;

    public int getC1() {
        return c1;
    }

    public int getC2() {
        return c2;
    }

    public int getC3() {
        return c3;
    }

    public int getC4() {
        return c4;
    }

    public void cut() {
        im = new ImagePanel();
        GraphicalUserInterface.getFrame().add(im);
        im.addMouseMotionListener(this);
        im.addMouseListener(this);
    }

    public void draggedScreen() throws Exception {
        int w = c1 - c3;
        int h = c2 - c4;
        w = w * -1;
        h = h * -1;
        Robot robot = new Robot();
        BufferedImage img = robot.createScreenCapture(new Rectangle(c1, c2, w, h));
        File save_path = new File("screen1.jpg");
        ImageIO.write(img, "JPG", save_path);
        GraphicalUserInterface.getLabelIcon().setIcon(new ImageIcon(new ImageIcon(img).getImage().getScaledInstance(img.getWidth(),img.getHeight(),Image.SCALE_SMOOTH)));
        JOptionPane.showConfirmDialog(null,"Would you like to save your cropped Pic?");
        if(JOptionPane.YES_OPTION == 0){
            PicChanges.getCurrentLabel();
        } else {
            PicChanges.getCurrentLabel();

        }
        System.out.println("Cropped image saved successfully.");
    }

    @Override
    public void mouseClicked(MouseEvent arg0) {
    }

    @Override
    public void mouseEntered(MouseEvent arg0) {
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
    }

    @Override
    public void mousePressed(MouseEvent arg0) {
        repaint();
        c1 = arg0.getXOnScreen();
        c2 = arg0.getYOnScreen();
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
        repaint();
        if (drag_status == 1) {
            c3 = arg0.getXOnScreen();
            c4 = arg0.getYOnScreen();
            try {
                this.repaint();
                draggedScreen();
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("Issue is under construction");
        }
    }

    @Override
    public void mouseDragged(MouseEvent arg0) {
        repaint();
        drag_status = 1;
        c3 = arg0.getXOnScreen();
        c4 = arg0.getYOnScreen();
    }

    @Override
    public void mouseMoved(MouseEvent arg0) {
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        int w = c1 - c3;
        int h = c2 - c4;
        w = w * -1;
        h = h * -1;
        if (w < 0)
            w = w * -1;
        g.setColor(Color.RED);
        g.drawRect(c1, c2, w, h);
        System.out.println("paint component");

    }
}

public class ImagePanel extends JPanel {
    private BufferedImage imageToCut;

    public ImagePanel() {
        Dimension size = new 
        Dimension(GraphicalUserInterface.getLabelIcon().getSize());
        setPreferredSize(size);
        setMaximumSize(size);
        setMinimumSize(size);
        setSize(size);
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.drawImage(imageToCut, 0, 0, null);
        System.out.println("painted");
    }
}

I'm confused as I can't figure out how to invoke paint() method, that's why as of now, the image is cropped and correctly but the rectangle is not drawn. As far as I understand my paintComponent() method is working as I invoke ImagePanel class and add MouseListeners to it where the repaint() method is called.

To invoke the paint() method I need to invoke ImageScreenShot class but here where the issues arise.

So my question is how to invoke paint() method called by repaint() method in the MouseListeners of ImageScreenShot class?

Frakcool
  • 10,915
  • 9
  • 50
  • 89
Ilona
  • 357
  • 3
  • 10

2 Answers2

1

I haven't tested your code, but at first glance I can see that:

  1. You're extending JPanel, that's fine, but you're overriding paint(...) method, you should not do that, you need to override paintComponent(...)

  2. On your second class you're overriding paintComponent(...) but you're not calling

    super.paintComponent(g);
    

    Which, is breaking the paint chain. And probably (along with 1st point) is the cause of your error.

  3. See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes), you need to override the getPreferredSize() and call pack() in your application.

Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • Thank you for the hints and a link. getPrefferedSize() was really one of the issues I should have covered. – Ilona Apr 26 '19 at 07:04
0

Use arg0.getComponent().repaint(); where arg0 is the MouseEvent. It will repaint the component where the event is fired. See https://docs.oracle.com/javase/8/docs/api/java/awt/event/ComponentEvent.html#getComponent--

Returns: the Component object that originated the event, or null if the object is not a Component.

hkn
  • 1,453
  • 19
  • 21