简体   繁体   English

Repaint()方法不会一一调用paint()和paintComponent()方法,只有paintComponent()方法有效

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

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. 我要实现的是根据从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. 我很困惑,因为我不知道如何调用paint()方法,这就是为什么到目前为止,图像被正确裁剪并正确绘制但矩形未绘制的原因。 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. 据我了解,当我调用ImagePanel类并在调用repaint()方法的位置添加MouseListeners ,我的paintComponent()方法正在工作。

To invoke the paint() method I need to invoke ImageScreenShot class but here where the issues arise. 要调用paint()方法,我需要调用ImageScreenShot类,但是在这里出现问题。

So my question is how to invoke paint() method called by repaint() method in the MouseListeners of ImageScreenShot class? 所以我的问题是如何在ImageScreenShot类的MouseListeners中调用由repaint()方法调用的paint()方法?

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(...) 您正在扩展JPanel ,这很好,但是您覆盖了paint(...)方法,则不应该这样做,需要覆盖paintComponent(...)

  2. On your second class you're overriding paintComponent(...) but you're not calling 在第二堂课上,您覆盖了paintComponent(...)但没有调用

     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? 请参阅我应该避免在Java Swing中使用set(Preferred | Maximum | Minimum)Size方法吗? (Yes), you need to override the getPreferredSize() and call pack() in your application. (是),您需要在应用程序中覆盖getPreferredSize()并调用pack()

Use arg0.getComponent().repaint(); 使用arg0.getComponent().repaint(); where arg0 is the MouseEvent. 其中arg0是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-- 参见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. 返回:引发事件的Component对象;如果该对象不是Component,则返回null。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM