In order to draw images and or shapes in my JFrame, I use a very common method that works.
I use a class that extends canvss, make my own custom JFrame object then add my own class (which extends camvas). Then, I override the 'paint' method in order to paint on the canvas.
Basicly, here is an example: http://pastebin.com/KhZudT3r
This whole process works perfectly, but I was wondering if there's a way to draw on a jframe (perferebly a canvas) without having to extend the canvas class?
Thanks,
Jake
Try with JPanel and override paintComponent() method for your custom painting.
Don't forget to call super.paintComponent(g) in overridden method.
Never draw directly on JFrame itself instead draw on JPanel and then add it into JFrame
Sample code:
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//your custom drawing here
}
};
Related
I am making a game in which I move a square with my mouse, but when I move my mouse the old squares do not delete, which results in a trail of squares. I would like it to only have the one square which is following my mouse. This is currently my code. I have read to use paintcomponents but I am not sure how to use it since I am still a beginner.
This is in my "GamePanel" Class
public void mouseMoved(MouseEvent m) {
Graphics g= this.getGraphics();
h.changeX(m.getX());
h.changeY(m.getY());
h.drawHero(g);
}
This is in my "Hero" Class
public void drawHero(Graphics g){
g.drawImage(heroPic,stX,stY,null); //heroPic is a picture I imported
Don't use the this.getGraphics(). That is something you will definitely not want to to do, since it produces artifacts (as you mentioned).
It would be better to store the mouse position as a variable, then handle all the rendering when the paintComponent(Graphics) method has been called. Be sure to also call super.paintComponent(Graphics) to get rid of artifacts.
Generally, you should only handle graphics inside the paintComponent(Graphics) method and in any methods that are called only from the paintComponent(Graphics) method.
Here is a question which touches on why you should avoid Component#getGraphics(): Drawing an object using getGraphics() without extending JFrame
Here is another question I answered revolving around rendering with graphics: Java JFrame draw
Use a seperate class that extends JPanel :
class DrawPane extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(heroPic, x, y, this);
}
}
Then create a variable that will hold this class object :
DrawPane dp = new DrawPane();
after that set the variable to the contence pane. :
JFrame.setContencePane(dp);
Now to repaint this do :
dp.repaint();
Do not worry about the 'Graphics g' you wont have to input anything.
I created a class called Test, most likely where I went wrong.
import javax.swing.JPanel;
import java.awt.*;
public class Test extends JPanel {
Graphics grap;
public void sun()
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
As you can see I want to paint a yellow "Oval" in the top left corner of the panel using a method but I did not use a PaintComponent method. Now I try to implement it in my Paint component method which is in a class called Painting.
//import...;
public class Painting extends JPanel{
protected void paintComponent(Graphics g)
{
Test test = new Test();
test.sun();
}
And now i created a main window that will create a panel and display the yellow oval.
//import...
public class main extends JFrame{
public static main(String [] args){
JFrame window = new JFrame();
window.add(new Painting());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(100,100);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
}
But this does not work. I have a feeling that it is the sun method in test. How would I get this to work? I have looked in all the java books and cant find anything that can help.
Please note that I do not what to add parameters to the method.
Thank You
Tom.
Few points to be noted here:
Never call super.paintComponent by yourself except within the overriden paintComponent method itself.
If you want to do some Graphics activities then override the paintComponent method and draw graphics over there
When you are overriding paintComponent method then the first statement within the method should be super.paintComponent(g).
Now, going by all above points your code should now be like this:
public class Test extends JPanel {
public void paintComponent(Graphics grap)
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
And your Painting class should be like this:
public class Painting extends JPanel{
Test test;
public Painting()
{
test = new Test();
setLayout(new BorderLayout());
add(test);
}
}
If i want to draw 50 ovals on different places then i would have a problem with extensive code
Then you would keep a List of the ovals that you want to paint. See Custom Painting Approaches which paints a bunch of Rectangles on a panel. All the code does is loop through the ArrayList to paint the Rectangle. Only a couple of lines of code are required.
I have a JFrame with a JPanel on it (JPanel is private in JFrame). Now I want to override JPanel by using paintComponent method.
How can I do that?
When you create your instance of JPanel, (assuming you're doing it this way), do this:
JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
// paint code
}
};
The other alternative is to create a private class which extends JPanel.
For example:
public class OuterClass{
// fields, constructors, methods etc..
private class MyPanel extends JPanel{
// fields, constructors, methods etc..
#Override
public void paintComponent(Graphics g){
// paint code
}
}
}
not clear from your question, but I think that nothing complicated override paintComponent for Swing JComponents, please avoid to use method paint() for Swing JComponents, use only paintComponent()
I have a situation wherein I have a bunch of JButtons on a GridLayout. I need each of the JButtons to have:
a background image (but retain the ability to keep the default button look if needed)
custom graphics drawn on top by other classes
I have no trouble with the background image, since I am using setIcon() but I am having problems drawing things on top of the background. At one point I was able to draw on top of the button, but after the button was clicked, the drawings disappeared. How can make the button keep this drawing state?
Basically, I need a way for my JButtons to have public methods that would allow another class to draw anything on it such as:
public void drawSomething() {
Graphics g = this.getGraphics();
g.drawOval(3,2,2,2);
repaint();
}
or
public Graphics getGraphics() {
return this.getGraphics();
}
then another class could do this:
button.getGraphics().drawSomething();
The latter is more what I am looking for but the first is equally useful.
Is there any way to go about this? Also, overriding the parent class method paintComponent() doesn't help since I need each button to have different graphics.
you can subclass JButton and override paintComponent().
you can handle each button having a different graphic by providing an external 'painter' to the subclass. Or just have a different subclass for each different graphic.
public class MyButton extends JButton {
private Painter painter;
public void paintComponent(Graphics g) {
super.paintComponent(g);
painter.paint(g);
}
}
public interface Painter {
public void paint(Graphics g);
}
you cannot just paint on the button as you are doing as the painting will get lost when the button is next repainted.
You can create a BufferedImage and do custom painting on it and then draw the image in your custom paintComponent(...) method.
Look at the DrawOnImage example from Custom Painting Approaches.
I created a new JApplet form in NetBeans:
public class UI extends javax.swing.JApplet {
//generated code...
}
And a JPanel in design mode named panou:
// Variables declaration - do not modify
private javax.swing.JPanel panou;
How do I get to draw a line on panou? I've been searching for this for 5 hours now so a code snippet and where to place it would be great. Using Graphics2D preferably.
Go to design mode
Right Click on the panel "panou"
Click "Costumize code"
In the dialog select in the first combobox "costum creation"
add after = new javax.swing.JPanel() this, so you see this:
panou = new javax.swing.JPanel(){
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g); // Do the original draw
g.drawLine(10, 10, 60, 60); // Write here your coordinates
}
};
Make sure you import java.awt.Graphics.
The line that you will see is always one pixel thick. You can make it more "line" by doing the following:
Create this method:
public static final void setAntiAliasing(Graphics g, boolean yesno)
{
Object obj = yesno ? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF;
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, obj);
}
And add after super.paintComponent(g); (in your costum creation) this:
setAntiAlias(g, true);
Edit:
What you are doing wrong is: you paint the line once (by creating the frame).
When you paint the line the frame is also invisible. The first draw is happening when the frame becomes visible. The frame will be Repainted, so everything from the previous paint will disappear.
Always you resize the frame, everything will be repainted. So you have to make sure each time the panel is painted, the line also is painted.
To do custom painting in a JPanel, one would need to make a subclass of a JPanel, and then overload the paintComponent method:
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
// Perform custom painting here.
}
}
In the example above, the MyPanel class is a subclass of JPanel, which will perform whatever custom painting is written in the paintComponent method.
For more information on how to do custom painting in Swing components, Lesson: Performing Custom Painting from The Java Tutorials have some examples.
If one wants to do painting with Java2D (i.e. using Graphics2D) then one could do some painting on a BufferedImage first, then draw the contents of the BufferedImage onto the JPanel:
class MyPanel extends JPanel {
BufferedImage image;
public MyPanel() {
Graphics2D g = image.createGraphics();
// Do Java2D painting onto the BufferedImage.
}
public void paintComponent(Graphics g) {
// Draw the contents of the BufferedImage onto the panel.
g.drawImage(image, 0, 0, null);
}
}
Further reading:
Painting in AWT and Swing
Trail: 2D Graphics