I was studying graphics and tried to use PaintComponent to draw some shapes, following is the code. I am trying for an hour but still its not working really can't get reason. What is the resolution to this simple problem?
public class MyPainting extends JPanel
{
public void PaintComponent (Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(100, 100, 10, 20);
}
public static void main (String [] args)
{
MyPainting p = new MyPainting();
JFrame f= new JFrame();
f.setSize(300,300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
f.setVisible(true);
}
}
When I run program there is empty JFrame, I did try it g.drawString, ImageIcon but every time nothing is visible.
The method PaintComponent is not defined in any of the super classes of JPanel. You want paintComponent
#Override
public void paintComponent (Graphics g)
and add the #Override annotation to allow compiler check for the correct method.
Related
I created a frame and panel (for Graphics) and add buttons to the panel. However, when I run my program buttons are not visible until I hover over them. Maybe it is something wrong with graphics methods.
How the problem can be solved?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main{
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(600,500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
Panel panel = new Panel();
f.add(panel);
f.setVisible(true);
}
}
class Panel extends JPanel implements ActionListener{
int[] x = {200,400,300,200};
int[] y = {100,100,200,100};
JButton fillRed;
JButton fillBlack;
JButton cancel;
Panel(){
this.setLayout(null);
fillRed = new JButton("Red");
fillRed.setBounds(50, 400, 100, 50);
fillRed.addActionListener(this);
this.add(fillRed);
fillBlack = new JButton("Black");
fillBlack.setBounds(250, 400, 100, 50);
fillBlack.addActionListener(this);
this.add(fillBlack);
cancel = new JButton("Cancel");
cancel.setBounds(450,400,100,50);
cancel.addActionListener(this);
this.add(cancel);
}
public void paint(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
}
public void fillRed(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillPolygon(x,y,4);
}
public void fillBlack(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillPolygon(x,y,4);
}
public void cancel(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==fillRed) {
fillRed(getGraphics());
}
if(e.getSource()==fillBlack) {
fillBlack(getGraphics());
}
if(e.getSource()==cancel) {
cancel(getGraphics());
}
}
}
Your painting code is mostly wrong. For example:
public void paint(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
}
If you need to override paint() then the first statement should be super.paint(g).
However, you should NOT override paint. For custom painting you override paintComponent(...) and then invoke super.paintComponent(g). Read the Swing tutorial on Custom Painting for more information and working examples.
public void fillBlack(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillPolygon(x,y,4);
}
Never invoke paintComponent(...) directly. If you need to change a property of a component then you invoke repaint() and Swing will invoke the painting methods.
if(e.getSource()==fillRed) {
fillRed(getGraphics());
}
Don't invoke getGraphics() on a Swing component. Painting is done by setting properties of your class and then you invoke repaint(). If you need to paint multiple objects then you need to keep track of each object you want to paint and then in the painting method you paint every object. Check out Custom Painting Approaches for example of how this can be done.
I wrote the following code. Everything works fine. There are no compilation errors. yet I see only a yellow window and nothing else. I am posting my paintcomponent method here.
my paintcomponent method
#Override
public void paintComponent(Graphics g)
{super.paintComponent(g);
g.setColor(Color.red);
g.drawRect(x,100,150,200);
fh++;
}
}
I tried extending Jpanel,JFrame,Jcomponent,etc
I tried paint() as well as paintComponent()
I am adding full code for reference
my code
import javax.swing.*;
import java.awt.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
class painting extends JPanel
{static Component c=new Canvas();
static JFrame f=new JFrame();
int fh;
int x=50;
public void main(String args[]) throws InterruptedException
{
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.add(c);
f.setVisible(true);
f.setSize(300,320);
/*
c.setSize(200,220);
c.setBackground(Color.yellow);
c.setForeground(Color.red);
c.setVisible(true);
*/
for(;x<200;x++)
{x=x+10;
repaint();
Thread.sleep(10);
}
}
#Override
public void paintComponent(Graphics g)
{super.paintComponent(g);
g.setColor(Color.red);
g.drawRect(x,100,150,200);
fh++;
}
}
A component’s paintComponent method is only called if that component is added to a window. You added a new Canvas() to your window, but you never added an instance of your own specialized panel, painting, to your window.
You can fix it by removing this:
static Component c=new Canvas();
and replacing this:
f.add(c);
with this:
f.add(new painting());
I'm trying to find what is wrong with this short code. I can't print the String TEXT in my JFrame using drawString() method. Please Help . Only a plain white screen will appear if you run the program .
Code:
import javax.swing.*;
import java.awt.*;
public class sample extends JFrame
{
private JPanel panel;
public sample()
{
setSize(500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
panel =new JPanel();
Container mainP= getContentPane();
mainP.add(panel);
panel.setBounds(0,0,500,500);
panel.setBackground(Color.WHITE);
}
public void paintComponent(Graphics g)
{
Graphics2D eg = (Graphics2D)g;
eg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
eg.setColor(Color.BLACK);
eg.drawString("TEXT", 40, 120);
}
public static void main(String args[])
{
new sample();
}
}
JFrame has no paintComponent method. So you aren't override anything, and not painting will be done.
On that note JPanel does have a paintComponent method, and you should be painting on a JComponent or JPanel, which do have the method. You don't want to paint on top-level containers like JFrame. (if you really need to know though, the correct method to override is paint for JFrame).
That being said, you should also call super.paintComponent inside the paintComponent method so you don't break the paint chain and leave paint artifacts.
Side Notes
As good practice, make use of the #Override annotation, so you know you are correctly overriding a method. You would've seen that paintComponent doesn't override one of JFrames methods.
setVisible(true) after add your components.
panel.setBounds(0,0,500,500); will do absolutely nothing, since the JFrame has a default BorderLayout
Follow Java naming convention and use capital letters for class names.
Run Swing apps from the Event Dispatch Thread. See more at Initial Threads
FINAL
import javax.swing.*;
import java.awt.*;
public class Sample extends JFrame {
private JPanel panel;
public Sample() {
setSize(500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D eg = (Graphics2D) g;
eg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
eg.setColor(Color.BLACK);
eg.drawString("TEXT", 40, 120);
}
};
Container mainP = getContentPane();
mainP.add(panel);
panel.setBackground(Color.WHITE);
setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Sample();
}
});
}
}
This is a pretty simple program that just draws a white rectangle in a pop-up window. The program compiles and runs no problem, and the windoe pops up, but there is nothing in it, it's just grey. Why isn't anything drawing?
import java.awt.*;
import javax.swing.*;
public class DrawPanel extends JPanel {
public void paintcompnent(Graphics g) {
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(10, 10, 200, 200);
}
public static void main(String[] args) {
DrawPanel panel = new DrawPanel();
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(panel);
window.setSize(550,550);
window.setVisible(true);
}
}
public void paintcompnent(Graphics g)
Should be
public void paintComponent(Graphics g)
You have not correctly overridden the method. It should be:
#Override
protected void paintComponent(Graphics g) {}
Note the use of the #Override annotation, which will prevent you from making this mistake in the future.
After fixing the overridden method name, it still won't paint anything because you are filling the rectangle in white and then painting white lines on top. You need to use setColor() to set something other than white to see the lines.
Why JFrame is empty after my graphics
package javaGame;
import java.awt.Graphics;
import javax.swing.JFrame;
public class javaGame extends JFrame {
public javaGame (){
setVisible(true);
setSize(250,250);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Java Game");
}
public void paint (Graphics g){
g.drawString("Hello world!", 75, 75);
}
public static void main (String[] args){
new javaGame ();
}
}
You are used to applets, where overriding paint will actually work. In a JFrame, the recommended technique is a little more complicated. Add this code to your constructor:
getContentPane().add(new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hello world!", 75, 75);
}
});
This creates an anonymous subclass of JPanel which overrides paintComponent to do some painting, then adds the JPanel to the frame. The call to super.paintComponent is important.
There are several other things that you should know are different from applets:
You need to call setVisible(true) to make the frame appear. This is mandatory for your program to work.
You should add setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) if you want the program to be closed if the window is closed. Highly recommended.
When you opening a new frame you should make it visible after validate or pack is applied to it, also call setVisible(true) at the end of the frame creation. The code for modification:
public void paint (Graphics g){
super.paint(g);
g.drawString("Hello world!", 75, 75);
}
1) Follow java code conventions javaGame should be JavaGame
2) Swing programs should override paintComponent() instead of overriding paint().
3) You should make custom painting in a JComponent like JPanel.
Change your code to for example something like this.
public class JavaGame {
private JFrame frame; //use composition instead of concrete inheritance
public JavaGame () {
jframe.setSize(250,250);
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setTitle("Java Game");
jframe.add(new JPanel() {
#Override
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawString("Hello world!", 75, 75);
}
});
jframe.pack(); //sizes the frame
jframe.setVisible(true);
}
public static void main (String[] args) {
SwingUTilities.invokeLater(new Runnable() {
#Override
public void run() {
new javaGame();
}
});
}
}