I watched a tutorial and tried to do same thing, I wrote the codes exactly the same but it shows nothing. I think it is because paintComponent method is not being called, I also tried to print something to console by paintComponent.
Here is my code:
public class Line extends JPanel{
#Override
public void paintComponents(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.drawLine(100, 10, 30, 40);
}
public static void main(String[] args) {
Line l =new Line();
JFrame myFrame = new JFrame("Line");
myFrame.setSize(600, 400);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.add(l);
myFrame.setVisible(true);
}
}
Thank you!
What you want to override is paintComponent, not paintComponents with a s .
paintComponents paints the child components of the current component (well it sort of tells the child components to paint themselves on the Graphics object).
paintComponent paints the component itself, this is the method you want to override to do custom painting for your component.
Related
I have been playing around with Java's 2d painting tools and have hit a snag. I am attempting to move the objects. Here is the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Test extends JPanel{
private int[] location = new int[2];
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillArc(location[0], location[1], 100, 100, 45, 90);
g.setColor(Color.black);
g.fillArc((location[0]+50-10),(location[1]+50-10), 20, 20, 0, 360);
new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
setLocation((location[0]+50),50);
repaint();
System.out.println("repainting");
}
}).start();
}
public void setLocation(int x, int y){
this.location[0] = x;
this.location[1] = y;
}
public static void main(String[] args){
JFrame jf=new JFrame();
jf.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
jf.setPreferredSize(new Dimension(300,500));
jf.setLocation(100,100);
jf.add(new Test());
jf.pack();
jf.setVisible(true);
}
}
This only paints one of the two objects to the screen... it seems to be the second one as when I change the parameters of setLocation on [1] the one object it does paint moves. Any thoughts? Thanks
Edit: Edited above code to reflect what was said below.
You are adding two components to the JFrame in a default way. This will add the components BorderLayout.CENTER and so the second component will cover and obscure the first. You will want to read up on layout managers to fix this. Also read up on Swing Timers for simple animations, since your code, even if written correctly would do no animation.
If you want to move the drawing, then
Use only one Test JPanel
Override JPanel's paintComponent(...) method, not paint(...) method.
call the super.paintComponent(g) method first thing in your paintComponent method override.
Give the Test JPanel public methods to allow outside classes to change the location without having them directly futz with the field. Make the location field (name should begin with a lower-case letter) private just to be safe.
Use a Swing Timer to periodically call this method and change location, then call repaint() on the JPanel.
I have an assignment to create a paint program in Java. I have managed to create something but not exactly what I wanted.
My problem is that I cannot create a JFrame in my IDE(NetBeans 7.0.1) from the options that the IDE gives me, and call the paint classes correctly.
To be more specific I want to press a button from one panel(ex. Panel1) and paint in Panel2,in the same frame.
That's the calling of the class:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
PaintFlower102 f = new PaintFlower102();
}
Part of Class:
super("Drag to Paint");
getContentPane().add(new Label ("Click and Drag"),BorderLayout.SOUTH);
// add(new JButton("Brush 20"),BorderLayout.NORTH);
addMouseMotionListener( new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent event) {
xval=event.getX();
yval=event.getY();
repaint();
}
});
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(PaintFlower102.DISPOSE_ON_CLOSE);
}
public void paint(Graphics g) {
g.fillOval(xval, yval, 10, 10);
}
The problem is that if I do not put the extend JFrame in the class this doesn't work. And if I do, it creates a new frame in which I can draw.
Suggestions:
Don't ever paint directly in a JFrame except under rare circumstances of absolute need (this isn't one of them).
Instead paint in a JPanel or JComponent or other derivative of JComponent.
Paint in the class's paintComponent(Graphics g) method, not in paint(Graphics g).
Read the Java tutorials on this as it's all explained well there. Check out Trail: 2D Graphics and Performing Custom Painting.
I might be wrong, but I think that you need to include super.paintComponent(g), and override the paintComponent method like Hovercraft Full Of Eels said.
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw Oval
g.fillOval(xval, yval, 10, 10);
}
i simply implemented class that inherits JPanel like below
public class Orpanel extends JPanel {
....
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(tpaint);
g2d.fill(rect);
}
....
}
class Orpanel is loading image and adjusting it's own size.
here's question.
Calling JFrame's setContentpane(Orpanel's instance) makes it works fine
but when i attach Orpanel to JFrame calling add() method instead of setContentpane (i know setcontentpane is not meaning attach.. anyway), it dosen't work.
finally figured out when i used add() method, Component that was added to JFrame doesn't call paintComponent() method. even though i call repaint() method manually, still paintComponent() method is not called.
did i miss something?
any help will be appreciated!
thx in advance.
Jaeyong shin.
i added extra code.
public Test(OwPanel op)
{
super();
Dimension monitor = Toolkit.getDefaultToolkit().getScreenSize();
op.setBackground(Color.white);
this.setBackground(Color.white);
this.setBounds(monitor.width / 2 - 200 , monitor.height / 2 - 200, 400, 400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle("test");
this.setLayout(null);
this.getContentPane().add(op);
//this.setContentPane(op);
this.setVisible(true);
this.validate();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
OwPanel op = new OwPanel("d:\\java_workplace\\img\\img1.jpg", 100, 100);
OwLabel ol = new OwLabel("d:\\java_workplace\\img\\img2.jpg", 300, 50);
Test tst = new Test(op);
tst.add(ol);
}
});
still doesn't work if setContentpane() method replaced to getContentpane().add().
don't be confused. Owpanel and Orpanel is same :)
In your sample code, I see you have chosen NOT to use a LayoutManager, that's a very bad idea, but anyway, sicne you go this way, I see one reason for your Orpanel.paintComponent() not being called: it is probably not visible inside the frame!
If you have no LayoutManager, then you must explicitly set the size and location (through setBounds()) of all components you add to the frame.
It is likely you didn't do it, hence the size of Orpanel instance is probably 0 hence it never gets painted.
Sounds like you're just using the wrong methods. You should be doing this when adding a panel to a frame:
frame.getContentPane().add(panel) ;
I have a JFrame on which I am using overriding the paint method to display some graphics. I also want to add a JPanel to it that will show up on top of the graphics. Right now, all I see is the graphics created from JFrame paint method.
Here's my JPanel:
public class NoteDraw extends JPanel {
public NoteDraw() {
setSize(200, 100);
setBackground(Color.BLACK);
}
#Override public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(0, 0, 100, 100);
}
}
Here's my JFrame:
public class ui extends JFrame {
public void paint(Graphics g) {
//do some drawing here...
}
}
Here's my main:
public class Main {
static ui main_gui = new ui();
public static void main(String[] args) {
NoteDraw note = new NoteDraw();
main_gui.getContentPane().add(note);
main_gui.setVisible(true);
}
}
You should NEVER override the paint() method of a JFrame (unless you really know what you are doing). This method is responsible for all the optimized painting behaviour of Swing.
Custom painting should always be done by overriding the paintComponent() method of a Swing component like you have done on your NoteDraw panel.
The reason the code in the paint method doesn't show is because the NoteDraw panel is opaque and therefore the panel paints over top of the Graphics code in your paint method.
So the solution is to move the Graphics painting code to the NoteDraw panel.
Or if you are trying to create some kind of background image for your frame then you can try using the Background Panel.
Or if you truly do need custom painting then you create a background panel and override the paintComponent() method. Then you set the layout to a BorderLayout and add this panel to the frame. Then you make your NoteDraw panel non-opaque and add it to the custom background panel. Now the background will show through on the NoteDraw panel.
Remember to call super.paint() when you override your paint() method.
This way, you still use the behavior defined in the parent class, and you can add your modifications safely.
Resources :
sun.com - Using the Keyword super
I cannot get this oval to draw on the JFrame.
static JFrame frame = new JFrame("New Frame");
public static void main(String[] args) {
makeframe();
paint(10,10,30,30);
}
//make frame
public static void makeframe(){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(375, 300));
frame.getContentPane().add(emptyLabel , BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
// draw oval
public static void paint(int x,int y,int XSIZE,int YSIZE) {
Graphics g = frame.getGraphics();
g.setColor(Color.red);
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
The frame displays but nothing is drawn in it. What am I doing wrong here?
You have created a static method that does not override the paint method. Now others have already pointed out that you need to override paintComponent etc. But for a quick fix you need to do this:
public class MyFrame extends JFrame {
public MyFrame() {
super("My Frame");
// You can set the content pane of the frame to your custom class.
setContentPane(new DrawPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);
}
// Create a component that you can actually draw on.
class DrawPane extends JPanel {
public void paintComponent(Graphics g) {
g.fillRect(20, 20, 100, 200); // Draw on g here e.g.
}
}
public static void main(String args[]){
new MyFrame();
}
}
However, as someone else pointed out...drawing on a JFrame is very tricky. Better to draw on a JPanel.
Several items come to mind:
Never override paint(), do paintComponent() instead
Why are you drawing on a JFrame directly? Why not extends JComponent (or JPanel) and draw on that instead? it provides more flexibility
What's the purpose of that JLabel? If it sits on top of the JFrame and covers the entire thing then your painting will be hidden behind the label.
The painting code shouldn't rely on the x,y values passed in paint() to determine the drawing routine's start point. paint() is used to paint a section of the component. Draw the oval on the canvas where you want it.
Also, you're not seeing the JLabel because the paint() method is responsible for drawing the component itself as well as child components. Overriding paint() is evil =)
You are overriding the wrong paint() method, you should override the method named paintComponent like this:
#Override
public void paintComponent(Graphics g)
You need to Override an exist paint method that actually up to dates your Frame. In your case you just created your custom new method that is not called by Frame default.
So change your method to this:
public void paint(Graphics g){
}