Repaint() method doesn't invoke paint() & paintComponent() methods one by one, only paintComponent () method is working

♀尐吖头ヾ 提交于 2019-12-13 04:08:50

问题


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?


回答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.




回答2:


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.



来源:https://stackoverflow.com/questions/55844963/repaint-method-doesnt-invoke-paint-paintcomponent-methods-one-by-one-o

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!