Why JFrame is empty after my graphics - java

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();
}
});
}
}

Related

Buttons not visible until mouseover

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.

Why paintComponent doesn't work?

I'm having issues with this code. For some reason, paintComponent(Graphics g) simply doesn't work and there doesn't seem to be an answer how to force it to. This is my code:
import javax.swing.JFrame;
public class Robotron extends JFrame
{
public Robotron ()
{
//add(this); This one gave me an error
setSize(800, 600);
new TestFrame();
setVisible(true);
}
public static void main(String [ ] args)
{
new Robotron();
}
and this is my TestFrame class that has the paintComponent function:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class TestFrame extends JPanel
{
public void paintComponent(Graphics g)
{
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.YELLOW);
g.fillRect(100, 100, 10, 30);
System.out.println("Abdullah Paint");
}
public TestFrame()
{
setFocusable(true);
repaint();
}
}
What can I do in order to make paintComponent actually play. What I get in the end is just an empty JFrame, with no running of the System.out.println thingy.
Thanks a whole lot, been tackling this for a long time.
You're not adding anything to the JFrame, because of this
//add(this);
Here, you were trying to add the component to itself, which is not going to fly.
Instead, you need to add the TestFrame instance to the Frame.
add(new TestFrame());
setSize(800, 600);
setVisible(true);
You need to add the panel to the frame:
public Robotron ()
{
//add(this); This one gave me an error
setSize(800, 600);
add(new TestFrame());
setVisible(true);
}
As mentioned by others, you need to add the panel to the frame:
public Robotron() {
add(new TestFrame());
setSize(800, 600);
setVisible(true);
}
As not mentioned by others, you need to call super.paintComponent(g) the first thing in your overridden method:
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.YELLOW);
g.fillRect(100, 100, 10, 30);
System.out.println("Abdullah Paint");
}
Notes:
Don't call repaint() in the constructor. At best it does nothing.
Don't call setSize(...) for the frame, instead call pack(). You will need to override the getPreferredSize method in your panel for this.

Can't print any string using drawString() in JFrame

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();
}
});
}
}

PaintComponent not working for drawing shapes

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.

Can not draw oval on a JPanel

I have a JFrame created with GUI builder of Netbeans, which contains a JPanel only. I have created a method getPanel for getting a reference to this JPanel:
public class ShowDrawings extends JFrame {
public ShowDrawings() {
initComponents();
}
public JPanel getPanel(){
return panel;
}
private JPanel panel;
}
In my main function I am doing:
public class Main {
public static void main(String[] args){
ShowDrawings sd = new ShowDrawings();
sd.setSize(800, 600);
Graphics g = sd.getPanel().getGraphics();
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
sd.getPanel().paint(g);
sd.repaint();
sd.setVisible(true);
}
}
But it does not draw anything. Please help me.
I have looked some related questions but they are all suggesting extending JPanel and overriding its paint method. But I did not want to do that way.
Thanks.
I have looked some related questions but they are all suggesting
extending JPanel and overriding its paint method. But I did not want
to do that way
You should not override JPanel paint() method, rather paintComponent(..). This is best practice and should be done if you want code that will not produce anomalies. Also doing it in your current approach (as you have seen) makes creating persistent drawings a lot harder as they are wiped away on repaint()
Rather extend JPanel and override paintComponent(Graphics g) not forgetting to call super.paintComponent(g) as first call in overridden paintComponent(..) method. Also dont forget to override getPreferredSize() of JPanel so that we can return correct dimensions and pack() may be called on JFrame (+1 to #mKorbels comment):
Here is some example code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
initComponents();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void initComponents() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel testPanel = new JPanel() {
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GREEN);
//g2d.drawOval(10,10,100,100);//I like fill :P
g2d.fillOval(10,10,100,100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
};
frame.add(testPanel);
frame.pack();
frame.setVisible(true);
}
}
The first time you repaint() your ShowDrawings sd frame anything you've painted like this (sd.getPanel().getGraphics().drawOval(...)) would be erased by the original JPanel#paintComponent() method.
As Andrew Thompson has written:
Do not use Component.getGraphics(). Instead, subclass and override the paint() (AWT), or paintComponent() (Swing) method.
Component.getGraphics() simply can't work. Java uses a callback mechanism for drawing graphics. You are not supposed to "push" graphics information into a component using getGraphics(). Instead you are supposed to wait until Java calls your paint()/paintComponent() method. At that moment you are supposed to provide the Component with the drawings you would like to do.
If you're just checking/debugging something you could even do something like this:
class Test {
private JPanel panel = new JPanel() {
public void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.drawOval(400, 300, 50, 50);
}
};
}

Categories

Resources