Reputation: 5446
I want to rotate a picture in Java to do the code that is in this page:
http://beginwithjava.blogspot.com/2009/02/rotating-image-with-java.html
So far what I have done is to open a new JFrame, and inside of it I have put a jPanel with a jLabel; this jLabel uses the icon property to load my image into the label. After that I have choosen the click mouse event from the label and put the following code:
private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
Graphics2D g2d=(Graphics2D)g; // Create a Java2D version of g.
g2d.translate(170, 0); // Translate the center of our coordinates.
g2d.rotate(1); // Rotate the image by 1 radian.
g2d.drawImage(image, 0, 0, 200, 200, this);
}
it compiles without errors, but when I click on the label the following error appears:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javaapplication74.NewJFrame.jLabel1MouseClicked(NewJFrame.java:94)
at javaapplication74.NewJFrame.access$000(NewJFrame.java:17)
at javaapplication74.NewJFrame$1.mouseClicked(NewJFrame.java:50)
at java.awt.Component.processMouseEvent(Component.java:6508)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
is there any way to fix this?
The error in line 94 points to:
g2d.translate(170, 0);
I have added the following code, but the image does not rotate:
package javaapplication74;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
/**
*
* @author
*/
public class NewJFrame extends javax.swing.JFrame {
/**
* Creates new form NewJFrame
*/
// Create a constructor method
Image image;
Graphics g;
int angle;
public NewJFrame() {
initComponents();
image = Toolkit.getDefaultToolkit().getImage("download.jpg");
}
public void paintComponent(Graphics g){
Graphics2D g2d;
g2d=(Graphics2D)g; // Create a Java2D version of g.
g2d.translate(60, 0); // Translate the center of our coordinates.
g2d.rotate(angle); // Rotate the image by 1 radian.
g2d.drawImage(image, 0, 0, 200, 200, this);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setIcon(new javax.swing.ImageIcon("C:\\Users\\Documents\\NetBeansProjects\\JavaApplication74\\src\\javaapplication74\\download.jpg")); // NOI18N
jLabel1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jLabel1MouseClicked(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(19, 19, 19)
.addComponent(jLabel1)
.addContainerGap(20, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(26, 26, 26)
.addComponent(jLabel1)
.addContainerGap(27, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(77, 77, 77)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(261, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(59, 59, 59)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(141, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jLabel1MouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
angle=20;
jLabel1.repaint();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
the image is the following:
what could be wrong?
Thanks
Upvotes: 0
Views: 970
Reputation: 347214
Painting in Swing should be done within context of paintComponent
method, as your example demonstrates.
What you should do is set a variable which acts as the current rotation angle in your mouseClicked
method and call repaint
Then, in your paintComponent
method, you do something like...
Graphics2D g2d=(Graphics2D)g; // Create a Java2D version of g.
g2d.translate(170, 0); // Translate the center of our coordinates.
// You'll need to define angleOfRotatiomInRadians
// as an instance variable like image
g2d.rotate(angleOfRotatiomInRadians); // Rotate the image by 1 radian.
g2d.drawImage(image, 0, 0, 200, 200, this);
Updated based on changes to original question
So based on you example code...
Mistake #1:
public class NewJFrame extends javax.swing.JFrame
Becuase...
Mistake #2:
public void paintComponent(Graphics g){
If you had used the @Override
annotation, the compiler would have told you that you were attempting to override a method which didn't exist within the parent class hierarchy, this would have been you first alarm bell.
What this means is, your paintComponent
method will never be called, because top level containers, like JFrame
don't actually have a paintComponent
method. You should also avoid extending from or painting directly to top level containers for a multitude of reasons.
Apart from double buffering issues, this would look you into a single container, making to difficult to re-use the UI. Instead, you should try and create your UIs on a JPanel
as a base, this allows you to decide when and where the component should be used, making it much more usable.
Take a look at Performing Custom Painting and Painting in AWT and Swing for more details about painting in Swing
Mistake #3:
jLabel1.repaint();
Isn't going to do much, as it contains a reference to an unmodified reference of the image, so repainting it won't do much anyway, in fact, because you're trying to draw the image yourself, using the label at all is just a waste of time
Mistake #4:
Relying on form editor when you're really not sure what you're doing. A form editor is a formidable tool, but you need to have an understanding of how the UI API works before you can make real use of it.
I'd also encourage developers to hand code there UIs to start with, it will give you a greater appreciation of what can be achieved and when to and when not to use the editor.
Custom painting is not a simple topic, especially when you don't have a lot of experience with the underlying API. Take some time to become familiar with what's available in the Swing API, how it works and when you should dive in and do your own thing.
As an example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class RotateImage {
public static void main(String[] args) {
new RotateImage();
}
public RotateImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new RotatePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RotatePane extends JPanel {
private double imageRotationAngle = 0;
private BufferedImage img;
public RotatePane() {
try {
img = ImageIO.read(new File("Java.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
imageRotationAngle += Math.toRadians(1);
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight()- img.getHeight()) / 2;
g2d.translate(x, y);
g2d.rotate(imageRotationAngle, img.getWidth() / 2, img.getHeight() / 2);
g2d.drawImage(img, 0, 0, this);
g2d.dispose();
}
}
}
Upvotes: 2