问题
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:
You're extending
JPanel
, that's fine, but you're overridingpaint(...)
method, you should not do that, you need to overridepaintComponent(...)
On your second class you're overriding
paintComponent(...)
but you're not callingsuper.paintComponent(g);
Which, is breaking the paint chain. And probably (along with 1st point) is the cause of your error.
See Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing? (Yes), you need to override the
getPreferredSize()
and callpack()
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