I got 2 classes:
- 1st. makes a frame (JFrame) and adds a panel (JPanel) on it
- second one makes the panel and draws a rectangle on it (at least i thought it would)
this is the first class
class Frame {
JFrame frame;
Panel panel;
void draw() {
frame = new JFrame ("qwertz");
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setSize(300,200);
panel = new Panel();
panel.setLayout(null);
panel.paint();
frame.add(panel);
}}
and the second
class Panel extends JPanel {
void paint() {
Graphics g = getGraphics();
g.drawRect(50,50,90,70);
}}
when i call the draw() method from the first class it throws this exception at me:
java.lang.NullPointerException
at Panel.paint(Panel.java:8) (( g.drawRect(50,50,90,70); ))
at Frame.draw(Frame.java:15) (( panel.paint(); ))
That's not how you're supposed to paint. To paint a component, override the paintComponent(Graphics g) method of the JPanel then call repaint();
class MyPanel extends JPanel {
#Override // <-- this makes a compiler error if you typod the method name
public void paintComponent(Graphics g) {
g.drawRect(50,50,90,70);
}
}
and
panel = new MyPanel();
panel.setLayout(null);
panel.repaint(); // <<---- Look here! It says repaint() not paint()
frame.add(panel);
Also, if all you have to do is paint on this panel, I'd consider using a plain-old Component, and overriding paint(Graphics g) instead of paintComponent(Graphics g). paintComponent(Graphics g) is exclusively for swing components.
instead of implementing the paint method, you should implement the paintComponent(Graphics g) method. This way, the graphics object you have is valid.
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)
You are trying to draw the panel before it is added to the Frame. Try to move frame.paint(); below frame.add(panel);. Additionally if you are using Swing you should use JPanel instead of Panel.
Related
I created a separate class for JFrame and JPanel, then draw (fillOval in a JFrame class) and draw (fillOval in a JPanel class), and a button that will just animate the JPanel components. But the problem is, whenever i repaint the JPanel class; ---- The JFrame components disappeared. I don't understand why is this happening. I want the JFrame component be permanent for every animation done in JPanel class.
Sample Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TryRepaintIssue extends JFrame
{
public TryRepaintIssue(){
thePanel panel = new thePanel();
add(panel);
setSize(1000,1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void paint(Graphics g){
super.paint(g);
g.fillOval(100,500,100,100);
}
public static void main(String[] args){
new TryRepaintIssue();
}
public static class thePanel extends JPanel{
private int y = 100, vector = 1;
public thePanel(){
JButton button = new JButton("Play");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
y += vector;
repaint();
}
});
add(button);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.fillOval(100,y,100,100);
}
}
}
The JFrame components disappeared.
The components do not disappear. The button and panel are still displayed.
I assume you mean the custom painting of the black circle disappears.
I don't understand why is this happening
The paint() method of the frame is responsible for painting all the child components of the frame. So it repaints the JPanel you add to the frame, which in turn paints the JButton you add to the panel.
It then paints the black circle on top of the panel.
When you click the button you repaint only the "panel" which causes the JButton and the red circle to be painted.
You lose the painting of the black circle because you no longer invoke the code to paint that circle.
If you want the black circle to remain you have a couple of options:
The best solution is to NOT override paint() on the frame. Instead do all the custom painting in your panel. So paint both the black and red circles.
repaint the entire frame in your ActionListener code:
//repaint();
SwingUtilities.windowForComponent(button).repaint();
use the Glass Pane as suggested in the answer by Tom.
You shouldn't override JFrame.paint, particularly without calling the super. Usually drawing in these situations is done on a glass pane.
I'm back with a problem about java-graphics by swing... I want to paint some stuff at a jframe, here is the code:
PaintUtil-class:
public class PaintUtil extends JPanel{
public PaintUtil(){
this.setFocusable(true);
this.requestFocus();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
System.out.println("Repainted");
g.drawstuff...
}
}
Main-class:
public static PaintUtil util = new PaintUtil();
JFrame frame = new JFrame();
frame.setSize(500,600);
frame.setRezisable(false);
frame.add(util);
frame.setDefaultCloseOperation( 3 );
frame.getContentPane().setColor(Color.BLACK);
setup(); //This add some buttons
frame.setVisible(true);
util.repaint(); //not working
util.paintComponent(frame.getGraphics()); //works
Can you guys help me?
There is no error, no message in the console, just nothing
frame.setLayout(null);
Don't use a null layout. Swing was designed to be used with layout managers. Get rid of that statement.
By default the size of your panel is (0, 0) so there is nothing to paint.
You will need to override the getPreferredSize() method of your panel so the layout manager can do its job.
Read the section from the Swing tutorial on Custom Painting for more information and working examples.
I'm currently making a game in Java with AWT. The main class extends Frame, and I've been using it to draw the graphics using .getGraphics() and .drawRect(). This has been working fine, except that when I add components like labels to the frame it stops rendering the graphics and only displays the components.
Don't
Use getGraphics() to paint. That is not the proper way.
Try and paint on top-level containers like JFrame
Instead
Paint on a JPanel or JComponent (I prefer the former)
Override the paintComponent(Graphics g) method of the JPanel. Do all your painting in this method, use the implicitly passed Graphics context. You never have to actually call paintComponent as it will be implicitly called for you.
See
Performing Custom Painting for more details on painting in Swing
Edit
Just noticed you are using AWT. You really should consider upgrading to Swing. Otherwise, instead of paintComponent, you're going to want to override paint, as AWT components don't have a paintComponent method. But I strongly urge you to use Swing
Example (Using Swing)
public class SimplePaint {
public SimplePaint() {
JFrame frame = new JFrame();
frame.add(new DrawPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
class DrawPanel extends JPanel {
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.fillRect(50, 50, 150, 150);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new SimplePaint();
}
});
}
}
I've been programming in Java for about six months now and have done many work with Graphics in JPanels and JFrames. But recently I got a problem. All the JFrames I've been making before were always setUndecorated(false), but I needed to make one that was setUndecorated(true). So I tried, like usual, just putting the frame.setUndecorated(true) above all the frame's specs, so it looked something like this:
public static void main(String[] args){
JFrame frame = new JFrame("Frame");
frame.setUndecorated(true);
frame.setSize(600, 800);
frame.setVisible(true);
frame.add(new custompanel());
}
And the custompanel class:
public class custompanel{
public void paintComponent(Graphics g){
g.fillRect(100, 100, 100, 100);
}
}
The g in custompanel doesn't paint anything.
However, if I remove the frame.setUndecorated(true) or change it to frame.setUndecorated(false) it will paint a rectangle.
Any thoughts?
Assuming CustomPanel extends JComponent or JPanel, make the frame visible after adding CustomPanel. Calling super.paintComponent(g) is a good idea to paint any background components.
frame.setVisible(true);
I'm trying to paint an image on the screen after trying to use JLabel's and am now trying the paintComponent method. I tried inserting breakpoints after seeing no results and the method doesn't get called, and nothing appears. What should I do? Here is my important code-
`
public void createWindow(){
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setSize(xSize, ySize);
frame.setLocation(0, 0);
frame.addComponentListener(this);
//frame.add(im);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(placeholder, 0, 0, getWidth(), getHeight(), null);
g.drawString("Hello", 100, 100);
}
Also I'm using a JFrame instead of JPanel or component if that makes a difference.
JFrame does not have a paintComponent method. You should avoid painting directly to a frame and instead use a JPanel and override its paintComponent method
You should also make use of the #Override annotation, which will raise a compiler exception if the parent class does not have the method you are trying to override...