JPanel repaint() method issues [duplicate] - java

This question already has answers here:
Java Swing Blank JFrame coming up?
(2 answers)
Closed 6 years ago.
I am using a JPanel and JFrame class to create simple graphics in a window and have found a rather odd problem. My current setup is as such:
import javax.swing.JFrame;
public class MyFrame extends JFrame{
public MyFrame() {
super("App Schmapp!");
this.setSize(new java.awt.Dimension(500, 500));
this.setMinimumSize(this.getSize());
this.setMaximumSize(this.getSize());
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
MyPanel c = new MyPanel();
MyFrame a = new MyFrame();
a.add(c);
c.repaint();
}
}
Above is obviously my JFrame class and below is my JPanel class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class MyPanel extends JPanel {
public void paintComponent(Graphics G) {
super.paintComponent(G);
Graphics2D g = (Graphics2D) G;
g.setColor(Color.RED);
g.fillRect(50, 50, 50, 50);
}
}
My hope would be that this would work, however when I run this code a blank window pops up with no graphics. The part I don't understand is that if I changed the dimensions of the JFrame to something like 7000 by 10000 it works fine... please help?

Replace c.repaint(); to:
a.pack();
a.setVisible(true);
It should show red square as you wish.

Related

paint() in java with no display

import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
class game extends JFrame {
public game(){ //this is constructor
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(500,500);
frame.setTitle("Hello world");
}
public void paint(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Line2D line = new Line2D.Double(60,90,150,100);
g2.draw(line);
}
public static void main(String args[]) {
game l = new game();
}
}
The above code is compiling in java but on running the code it only displays the frame and its title, but does not include any of the lines being drawn using the Graphics2D and Line2D, what is the mistake that is being made??? The frame being displayed does not show any content, why is that???
First, you are creating and displaying a JFrame which is not an instance of game, so there is no chance that it paints what you have in the paint method of game .
You usually don't want to create a subclass of JFrame for custom painting anyway, just create a subclass of JPanel, and set it as the content pane of the frame.
Also don't override paint, but paintComponent, which is the method responsible for painting the current component.
You should also call the parent method of paintComponent, to make sure that all the usual cleaning takes place correctly.
Also by convention, class names should start with an upper case letter.
One last thing, make the frame visible only once you have added all your components, or you may encounter visual glitches some day.
Putting it all together :
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
class Game extends JPanel {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
Line2D line = new Line2D.Double(60, 90, 150, 100);
g2.draw(line);
}
public static void main(final String args[]) {
Game l = new Game();
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setTitle("Hello world");
frame.setContentPane(l);
frame.setVisible(true);
}
}
In your constructor call method of JFrame class using this keyword because you extends JFrame class in your class.
public game(){ //this is constructor
/*JFrame frame = new JFrame();
frame.setVisible(true);
frame.setSize(500,500);
frame.setTitle("Hello world");*/
this.setVisible(true);
this.setSize(500,500);
this.setTitle("Hello world");
}
This solve your problem.
you dont need to create instance of JFrame class ,
modified you constructor as shown below
public game(){ //this is constructor
setVisible(true);
setSize(500,500);
setTitle("Hello world");
}

JPanel Graphics not drawing anything (Java) [duplicate]

This question already has an answer here:
Can't draw to JPanel with getGraphics
(1 answer)
Closed 4 years ago.
I'm having trouble getting the graphics of my JPanel to work. It refuses to draw anything, regardless of anything I've tried and anything I can find on the internet.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Timer;
import java.util.*;
import java.io.*;
public class Mandelbrot{
public static void main(String[] args){
JFrame win=new JFrame();
JPanel dis=new JPanel();
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setResizable(false);
win.setVisible(true);
win.add(dis);
dis.setPreferredSize(new Dimension(1000,500));
win.pack();
Graphics g=dis.getGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, 100, 100);
}
}
Posting as an answer because I ran out of comment room:
Note:
If you need to be constantly changing things, then a JPanel is probably not your best option. I recommend you rethink what you are trying to do because you should probably use a Canvas or paint to a bunch of different labels/glass panes and overlay them however you want, this will allow you to have moving components/animations in a foreground item, and make different changes to the background item.
Alternatively, you can make the JPanel draw a buffered image, or you can store a list of items to paint, and you can paint them each time. For the buffered image method you can directly edit and draw to the buffered image every time you need to make a change.
Below is an example of how to use the buffered image method.
First create a custom JPanel in a new class:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class DrawPanel extends JPanel{
public BufferedImage canvas = new BufferedImage(panelWidth, panelHeight, BufferedImage.TYPE_INT_ARGB);
#Override
public void paintComponent(Graphics g){
//Draw the canvas
g.drawImage(canvas, 0, 0, this);
}
}
Now in your main method you can replace JPanel dis=new JPanel() with this:
DrawPanel dis = new DrawPanel();
Graphics g=dis.canvas.getGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, 100, 100);
Note how I use dis.canvas to get the graphics of the bufferedImage instead of the graphics of the JPanel.
It's as simple as that.
As per Andrews comment. You should consider extending a JLabel instead of a JPanel, it is much more lightweight, and easier to update using label.repaint();.
public static void main(String... args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
JPanel panel = new JPanel() {
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.red);
g.fillRect(0, 0, 100, 100);
}
};
panel.setPreferredSize(new Dimension(640, 480));
frame.add(panel);
frame.setVisible(true);
frame.pack();
}
Just an example - you should create a new Class subclassing JPanel, see Painting in AWT and Swing.

How would I draw on a JPanel to then be shown on a JFrame?

I've tried to research how Java's 2D rendering works, but I could never understand it. Here is the code in my main class:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main{
public static void main(String args[]) {
JFrame frame = new JFrame();
frame.setSize(new Dimension(500,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("JFrame testing");
frame.setVisible(true);
Frame panel = new Frame();
frame.add(panel);
}
}
And then here is for the JPanel class:
import java.awt.Graphics;
import javax.swing.JPanel;
public class Frame extends JPanel{
private static final long serialVersionUID = 1L;
public Frame() {
Graphics g = this.getGraphics();
g.drawRect(0, 0, 100, 100);
this.paintComponent(g);
}
}
I am also getting this exception, but I'm not sure what it means:
Exception in thread "main" java.lang.NullPointerException
at Frame.<init>(Frame.java:10)
at Main.main(Main.java:18)
I'm basically just trying to draw a rectangle onto a panel to be shown on the frame I've created. I've heard about the paintComponent method, but I also don't fully understand that.
You should Never use getGraphics() of a Component.
Try below code
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, 100, 100);
//this.paintComponent(g);
}
Edit
"why is super.paintComponent(g); called again inside the method?"
The documentation of paintComponent says it pretty well:
if you do not invoker super's implementation you must honor the opaque
property, that is if this component is opaque, you must completely
fill in the background in a non-opaque color. If you do not honor the
opaque property you will likely see visual artifacts.

Need to set frame.setResizable(false) to repaint() [duplicate]

This question already has answers here:
JFrame not presenting any Components
(4 answers)
Closed 5 years ago.
I am trying to buff my java skills (been about 10 years since I coded). Currently I am just trying to make a basic program that will have balls bouncing off the edges of the JFrame. However, as a starter in this program I tried drawing a line and box on the JPanel.
The issue I am finding is I have to call frame.setResizable(false) in order or the screen to paint my box and line. It will paint them if I resize the JFrame after it comes up. However, I would like it to paint as soon as the JFrame opens.
Putting in:
frame.setResizable(false);
frame.setResizable(true);
seems redundant. Is there a cleaner way to do this so it paints when the JFrame opens?
Below is my code if this helps:
MAIN CLASS
package bbs;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class BouncingBalls {
public static void main(String[] args) {
//Create the basic frame, set its size, and tell it to be visible
JFrame frame = new JFrame();
frame.setSize(800, 600);
frame.setVisible(true);
//Get a icon for the Program
ImageIcon logoicon = new ImageIcon("ball.jpg");
Image logo = logoicon.getImage();
frame.setIconImage(logo);
frame.setResizable(false);
frame.setResizable(true);
//find the center of the screen and where the frame should go
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = frame.getSize().width;
int h = frame.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
//Move the window
frame.setLocation(x, y);
//Tell the program to stop when the X button is selected
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Draw object = new Draw();
frame.add(object);
object.drawing();
}
}
PAINTING CLASS
package bbs;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Draw extends JPanel {
/**
* This is added to handle the serialization warning and is of the type Long to accommodate the warning
*/
private static final long serialVersionUID = 1L;
public void drawing(){
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(10, 20, 300, 200);
g.setColor(Color.BLUE);
g.fillRect(300, 200, 150, 200);
}
}
frame.setVisible(true);
This should be the last statement executed AFTER all components have been added to the frame.
Then all the components will paint normally.

How to import image into JPanel

I am working on an assignment (GASP) and having issues with my image displaying. I am not looking for someone to complete my assignment for me but I desperately need some help figuring out why my code is not working properly. I have reviewed my Java Programming book as well as searched for the answers online to no avail so if someone could lead me in the right direction I would greatly appreciate it!!
Here is my displayImage code:
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DisplayImage extends JFrame {
public void DislayImage(){
add (new ImagePanel());
}
public static void main(String[] args) {
JFrame frame = new DisplayImage ();
frame.setTitle("Go Bearcats!");
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Assignment02 a = new Assignment02();
frame.add(a);
}
}
class ImagePanel extends JPanel {
public final static String LOC = "C:\\UCincinnatiLogo.jpg";
private ImageIcon imageIcon = new ImageIcon (LOC);
private Image image = imageIcon.getImage();
#Override /**Draw image on the panel*/
protected void paintComponent(Graphics g){
super.paintComponent(g);
if (image !=null)
g.drawImage(image, 200, 200, getWidth(), getHeight(), this);
}
}
You're adding a component right on top of your image panel. The JFrame uses borderLayout, so anything added to it as you're doing will cover anything added previously.
JFrame frame = new DisplayImage ();
frame.setTitle("Go Bearcats!");
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Assignment02 a = new Assignment02();
frame.add(a); // here you add something on top of your imagePanel
Instead, make the ImagePanel the JFrame's contentPane via setContentPane(...), and then add things to the JFrame/contentPane, but be sure that they're not opaque.
public class DisplayImage extends JFrame {
public void DislayImage(){
setContentPane(new ImagePanel());
}
and then,
Assignment02 a = new Assignment02();
a.setOpaque(false);
frame.add(a);
Note, as an aside, I rarely create any classes that extend JFrame, and instead create my JFrame when needed. Instead I'd create my ImagePane and then add components directly to it before adding all to a JFrame.
Also you don't show us the Assignment02 class, but it had better have non-opaque JPanels and components.

Categories