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

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

Related

PaintComponent method not getting called

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

How to make a paint class that doesn't get called twice?

I wrote a paint class, and added the jpanel to the frame, but it's getting called twice for some reason, as I put a print statement inside the graphics method, and it printed it twice. The codes below are all the codes I have in my package.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Paint extends JPanel {
static Paint paint = new Paint();
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("Hello");
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(paint);
frame.pack();
frame.setLocation(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I tried your code and paintComponent it's not called twice every time. I don't think you have the control on when the JFrame is calling pack() when you call setVisible. It may depends on how your OS manage the windows.

Why JFrame is empty after my graphics

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

Graphics dont appear

Whatever I do, I can not display rectangle/line/oval on the screen. I checked other sources where they paint graphics, but when I even execute those codes, I don't get any graphics displayed on the windows. Below is the example from the text book.
import java.awt.*;
import javax.swing.*;
class PlotGraph
{
public static void main (String [] args) {
JFrame win;
Container contentPane;
Graphics g;
win = new JFrame("testing");
win.setSize(300,200);
win.setLocation(100,100);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
contentPane = win.getContentPane();
g = contentPane.getGraphics();
g.drawRect(10, 30, 50, 50);
}
}
Ouch. You should change your text book then. First of all, all the accesses to Swing components must be done in the event dispatch thread.
Second, you should not get the graphics of a component and paint on it. Instead, you should extend a JComponent or JPanel, override its paintComponent(Graphics) method, and paint using the Graphics object passed as argument (and which is in fact a Graphics2D instance).
That's not how graphics work in Swing.
You need to add a component to your frame, not just draw on it. You never want to draw directly on the frame. The reason why it's not doing anything is because your drawing code is being overridden.
If you want your component to have custom drawing code, make a subclass of JComponent and override the paintComponent(Graphics) method. An example of how you should do this is as follows:
import java.awt.*;
import javax.swing.*;
class PlotGraph {
public static void main(String[] args) {
JFrame win;
win = new JFrame("testing");
win.setSize(300, 200);
win.setLocation(100, 100);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
win.setContentPane(new MyComponent());
}
}
class MyComponent extends JComponent {
#Override
public void paintComponent(Graphics g) {
g.drawRect(10, 30, 50, 50);
}
}
I would highly encourage you to check out the Java GUI tutorial online.

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