I'm just going through some basic tutorials at the moment. The current one wants a graphics program that draws your name in red. I've tried to make a NameComponent Class which extends JComponent, and uses the drawString() method to do this:
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JComponent;
public class NameComponent extends JComponent {
public void paintMessage(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.drawString("John", 5, 175);
}
}
and use a NameViewer Class which makes use of JFrame to display the name:
import javax.swing.JFrame;
public class NameViewer {
public static void main (String[] args) {
JFrame myFrame = new JFrame();
myFrame.setSize(400, 200);
myFrame.setTitle("Name Viewer");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
NameComponent myName = new NameComponent();
myFrame.add(myName);
myFrame.setVisible(true);
}
}
...but when I run it, the frame comes up blank! Could anyone let me know what I'm doing wrong here?
Thanks a lot!
You need to override the method paintComponent rather than paintMessage. Adding the #Override annotation over the method will show that paintMessage is not a standard method of JComponent. Also you may want to reduce the y-coordinate in your drawString as the text is currently not visible due to the additional decoration dimensions of the JFrame. Finally remember to call super.paintComponent to repaint the background of the component.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.drawString("John", 5, 100);
}
See: Painting in AWT and Swing
You need to add this line after public void paintMessage(Graphics g){ :
super.paint(g);
This tells Java to use the superclass (JComponent) to paint the message.
You will also need to call your method paintComponents() rather than paintMessage()
Related
I'm making 2D drawing on Eclipse Oxygen, there are no error in my code but why it does not show any output. I mean when I click run there are no progress.
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.geom.Arc2D;
import java.awt.geom.Rectangle2D;
public class HOUSE1 extends Frame {
public void paint(Graphics2D g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawString("HOME SWEET HOME",80,60);
setBackground(Color.white);
Arc2D arc1 = new Arc2D.Double(250,50,500,300,225,90,Arc2D.Double.PIE);
g2d.draw(arc1);
g2d.setColor(Color.red);
g2d.fill(arc1);
Rectangle2D rect = new Rectangle2D.Double(325,300,350,300);
g2d.draw(rect);
g2d.setColor(Color.blue);
g2d.fill(rect);
Rectangle2D rect1 = new Rectangle2D.Double(325,300,350,300);
g2d.draw(rect1);
g2d.setColor(Color.black);
g2d.fill(rect1);
}
public static void main(String[]args){
HOUSE1 f = new HOUSE1();
f.setTitle("HOUSE");
f.setSize(300,100);
}
}
1st: In your main void you need to set your frame (f) to visible --> f.setVisible(true)
2nd: Also you might want to f.pack(); right before you set it to visible to to make sure your components are behaving like expected.
3th: In java we use a capital first letter in class like this "House", fully capital words are used for final's.
Your window is blank because your paint method is never called. Your method
public void paint(Graphics2D g) // DOESN'T WORK
needs to be changed to
public void paint(Graphics g) // Correct
so that it overrides the paint method in Frame. The graphics system will only call paint(Graphics); if your method called paint isn't overriding the method paint(Graphics) in Frame, the one in Frame gets called instead of yours.
You forgot to make your frame visible.
Just add :
f.setVisible(true);
You have to fix your paint method declaration to :
#override
public void paint(Graphics g) {
// your code
}
Can anyone help me out and tell me why the rectangle will not appear? The frame runs fine, but no shapes show up. I have tried doing this a couple of different ways, including with two separate classes, but all I get is an empty frame.
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Surface extends JPanel
{
public void paintComponent(Graphics2D g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(100, 100, 30, 40);
}
public static void main(String[] args)
{
Surface s = new Surface();
JFrame jf = new JFrame();
jf.setTitle("Tutorial");
jf.setSize(600, 400);
jf.setVisible(true);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(s);
s.repaint();
}
}
If you want to override a method, then annotate it correctly:
#Override
public void paintComponent(Graphics2D g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(100, 100, 30, 40);
}
then your IDE should tell you, that you're not overriding the paintComponent method correctly, because your parameter type Graphics2D is wrong.
This is the signature of the original/parent method in JComponent:
protected void paintComponent(Graphics g)
And as you can see, it uses Graphics instead of Graphics2D. You're currently overloading paintCompoent instead of overriding it. So change your parameter type to Graphics (and import java.awt.Graphics) and it will work:
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(100, 100, 30, 40);
}
By the way, you're setting the visibility of your jf first and then add something to its contentpane. In some case this can cause trouble and the added components won't be visible until you repaint the frame (or you do something else, which cause the frame to repaint itself, like calling pack()). So it might be best to switch the order of these method calls in your main method:
Surface s = new Surface();
JFrame jf = new JFrame();
jf.setTitle("Tutorial");
jf.setSize(600, 400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(s);
//s.repaint(); // not needed anymore, because "jf" will repaint everything during the 'setVisible' call
jf.setVisible(true); // should almost always be the last thing you do
I am currently working on a project, I get this error Java.lang.NullPointerException, I undrestand that this error happen when you try to refer to a null object instance, but what I do not know, is how I can fix it.
This is my code:
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawOval(150, 150, 10, 10);
}
/** Main Method **/
public static void main(String [] args) {
Run run = new Run();
run.paint(null);
}
Please help me with a solution and also explain it, so that I learn it. Many thanks in advance. Andre
You may not pass null to your paint method! Here is a small example how to do it:
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
class MyCanvas extends JComponent {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval (10, 10, 200, 200);
}
}
public class DrawOval {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
You almost never call paint methods (including paintComponent) directly as this is what the JVM should be doing.
Don't override the paint(Graphics g) method of a JComponent or JComponent derived class such as a JPanel if you can avoid it. This method, paint, is responsible for not only painting the component but also its borders and its child components, and if not done carefully, overriding this method will not infrequently result in unwanted side effects.
Later when you want to do graphics animation, overriding paint(Graphics g) will result in jerky graphics since it does not do double buffering by default.
By overriding the paintComponent(Graphics g) method instead you fix these issues.
Don't forget to call the super's paintComponent(g) method in your override to erase any unwanted previously drawn images.
Read the Swing Graphics tutorials, both the basic and advanced tutorials. Links at the bottom.
Better code:
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class MyBetterCanvas extends JComponent {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(10, 10, 200, 200);
}
public static void main(String[] a) {
MyBetterCanvas canvas = new MyBetterCanvas();
canvas.setPreferredSize(new Dimension(300, 300));
JFrame window = new JFrame("My Better Canvas");
window.getContentPane().add(canvas);
window.setLocationByPlatform(true);
window.pack();
window.setVisible(true);
}
}
Better Still:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class MyBetterStillCanvas extends JComponent {
private static final int PREF_W = 500;
private static final int PREF_H = 500;
private static final int OVAL_X = 10;
private static final int OVAL_Y = OVAL_X;
private static final Paint BG_PAINT = new GradientPaint(0, 20,
Color.black, 20, 0, Color.darkGray, true);
private static final Paint FILL_PAINT = new GradientPaint(0, 0,
Color.blue, 20, 20, Color.red, true);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// to smooth out graphics
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// let's draw something funky
g2.setPaint(BG_PAINT);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.setPaint(FILL_PAINT);
// avoid use of "magic" numbers
g.fillOval(OVAL_X, OVAL_Y, getWidth() - 2 * OVAL_X, getHeight() - 2
* OVAL_Y);
}
// a cleaner way to set the preferred size of a component
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public static void main(String[] a) {
JFrame window = new JFrame("My Better Canvas");
window.getContentPane().add(new MyBetterStillCanvas());
window.setLocationByPlatform(true);
window.pack();
window.setVisible(true);
}
}
Which displays as:
Tutorials:
Java Tutorials, Really Big Index
Java Swing Tutorials
Basic Swing Graphics Tutorial: Lesson: Performing Custom Painting
More Advanced Graphics Article: Painting in AWT and Swing
You are not doing it the right way. In order to use graphics in java you need to build upon Swing/AWT components. Currently you are passing Graphics as null.
run.paint(null);
You need to implement this using JFrame and other swing components.
Since you are sending null to paint, Graphics g contains null (points to nowhere).
Then inside paint(...) you call setColor(...) on g, which is null. null.setColor(...) causes NullPointerException.
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.
package donut;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
public class Board extends JPanel{
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
RenderingHints rh =
new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(rh);
Dimension size = getSize();
double w = size.getWidth();
double h = size.getHeight();
Ellipse2D e = new Ellipse2D.Double(0, 0, 80, 130);
g2.setStroke(new BasicStroke(1));
g2.setColor(Color.gray);
for (double deg = 0; deg < 360; deg += 5) {
AffineTransform at =
AffineTransform.getTranslateInstance(w / 2, h / 2);
at.rotate(Math.toRadians(deg));
g2.draw(at.createTransformedShape(e));
}
}
}
Then The JFrame Extended Class Where Board Object is instantiated
package donut;
import javax.swing.JFrame;
public class Donut extends JFrame {
public Donut() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(360, 310);
setLocationRelativeTo(null);
setTitle("Donut");
setVisible(true);
}
public static void main(String[] args) {
new Donut();
}
}
I was expecting to See Line Like this : new Board().paint(graphicsObject) So Where Actually This Line is executed Or in a proper way Where actually paint(Graphics g) function is called ?!
If you want to follow the invocation stack to paint(), simply write new Throwable().printStackTrace() or Thread.dumpStack(), this will allow you to follow the calling-stack.
Otherwise, have a look at RepaintManager.addDirtyRegion(JComponent, int, int, int, int);
Anyway, when you are painting to the screen, you should never call paint/paintComponent/paintXXX methods. Only call repaint().
You cannot rely on "when" your method paintComponent(Graphics) or paint(Graphics) will be invoked.
paint is automatically called by Swing whenever it is needed, for example when the component becomes visible (for the first time, or after a minimize of the window, etc), or when the window is resized, basically whenever the contents of a component need to be painted. You should never explicitly call paint in your code, if you wish to force paint then you should call repaint instead.
This link might be helpful
P.S. The code of paint method that is called by super.paint(g) resides in JComponent class, which is extended by JPanel (which is extended by your Board class).