Drawing oval in canvas using swing - java

I am new to Java and I have a problem with drawing an oval using paintComponent method. I found many similar threads, but none of the soultions worked. My code:
RacerMain.java
import javax.swing.*;
import java.awt.*;
public class RacerMain {
public static void main (String[]args) {
//MainFrame mf = new MainFrame();
JFrame jframe = new JFrame();
JPanel jpanel = new JPanel();
jframe.setSize(480,640);
jframe.add(jpanel);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jpanel.add(new Dot());
jframe.setVisible(true);
}
}
Dot.java
import java.awt.*;
import javax.swing.*;
public class Dot extends JComponent{
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.BLUE);
g2d.fillOval(20, 20, 20, 20);
}
}
Why it does not work and how to get this code working?

JPanel uses FlowLayout which respects preferred sizes but the default size of the Dot component is too small to be seen. You need to use a layout manager that uses the maximum area available or override getPreferredSize. Remember to call pack before calling JFrame#setVisible
jpanel.setLayout(new BorderLayout());

Or you can set preferred size in constructor:
import java.awt.*;
import javax.swing.*;
public class Dot extends JComponent {
public Dot() {
setPreferredSize(new Dimension(480, 640));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fillOval(20, 20, 20, 20);
}
}

Related

Graphics - Use a parameter (getSize()) to draw a line throughout the whole window

I need help here. I want to give a parameter to the drawLine() method which I get from getSize(). I want to draw a line throughout the whole window by using the getSize() method.
package PROG2;
import java.awt.*;
import javax.swing.*;
class MyComponent extends JComponent {
#Override
public void paintComponent(Graphics g) {
g.drawLine(100, 100, 200, 200);
}
}
public class Übung1 extends JFrame{
public static void berechnen() {
int height = frame.getHeight(); //Here it says it doesn't know "frame" variable but I don't know how to declare it here.
int width = frame.getWidth();
}
public static void main(String[] args){
JFrame frame = new JFrame("First window");
berechnen();
frame.add(new MyComponent());
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Graphics g = frame.getGraphics();
// int width = frame.getWidth();
// int height = frame.getHeight();
System.out.println("Größe:" + frame.getSize());
//System.out.println(width);
}
}
As Andrew already stated,
you don't want to get the dimensions or size of the JFrame but rather the component that is being displayed within the JFrame's contentPane, here your MyComponent instance.
The best place to get that information is inside of the paintComponent method itself, just prior to drawing the line.
And always call the super's painting method first
I also recommend:
Draw within a JPanel's paintComponent method, not a JComponent, if you want an opaque image
Avoid static methods and fields unless absolutely needed
Note that in the code below, the red line draws through the JPanel's diagonal, and continues to draw the diagonal, even when the JFrame is manually resized:
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.Stroke;
import javax.swing.*;
public class DrawLine extends JPanel {
private static final Stroke LINE_STROKE = new BasicStroke(15f);
private static final Dimension PREF_SIZE = new Dimension(800, 650);
public DrawLine() {
setPreferredSize(PREF_SIZE);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// code to make the line smooth (antialias the line to remove jaggies)
// and to make the line thick, using a wider "stroke"
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(LINE_STROKE);
// if we want a red line
g2.setColor(Color.RED);
// this is the key code here:
int width = getWidth();
int height = getHeight();
// draw along the main diagonal:
g2.drawLine(0, 0, width, height);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
DrawLine mainPanel = new DrawLine();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}

How do i ask paincomponent to draw things from other methods or classes

i want to ask paintcomponent from the TestGraphics class to draw a line, the way i'm doing it is just giving me a NullPointer Exception, i would be thankful for you if you could tell me how i could this
TestGraphics class:
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class TestGraphics extends JPanel {
public JPanel panel = new JPanel() {
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(120, 234, 23, 43);
}
};
}
Main class:
import javax.swing.*;
public class Main {
static int width = 600;
static int height = 800;
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestGraphics p = new TestGraphics();
// draw Line
p.panel.getGraphics().drawLine(123, 23, 43, 21);
frame.add(p.panel);
frame.setSize(height, width);
frame.setVisible(true);
}
}
You just need to add a new TestGraphics object, not to call " p.panel.getGraphics().drawLine(123, 23, 43, 21);". Here are the simple fixs:
TestGraphics.java
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class TestGraphics extends JPanel {
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(120, 234, 23, 43);
}
}
and Main.java
import javax.swing.*;
public class Main {
static int width = 600;
static int height = 800;
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestGraphics p = new TestGraphics();
// draw Line
frame.add(p);
frame.setSize(height, width);
frame.setVisible(true);
}
}
Here are small example: https://repl.it/repls/ExtrovertedSoulfulClients
To fix the immediately problem, you need to remove the line
p.panel.getGraphics().drawLine(123, 23, 43, 21);
because you are not allowed to call drawLine() outside of paintComponent().
Change
frame.add(p.panel);
to
frame.add(p);
and
public class TestGraphics extends JPanel {
public JPanel panel = new JPanel() {
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(120, 234, 23, 43);
}
};
}
to
public class TestGraphics extends JPanel {
public void paintComponent (Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawLine(120, 234, 23, 43);
}
}
Since TestGraphics already extends JPanel, you can add the p instance directly to the JFrame and override paintComponent() directly instead of creating an anonymous JPanel class.
From comments:
eventually i'll make constructors for lines, rectangles, triangles etc. i want to give paintcomponent some x and y values to draw said lines and rectangles and triangles
More specifically, you should make classes that represent each of these geometric objects. Each class should have a void paint(Graphics g) method. In fact, you should consider making an interface or abstract class GeometricObject with this method that you can call from your panel's paintComponent(). Your GraphicsTestclass can keep aListand callpaint(g)on each of them from itspaintComponent()`.
There will be a lot to learn about here: abstract classes, interfaces, lists, and loops, just to name a few. Good luck!

Graphics not drawing to JFrame

I feel like I went through everything I needed to do:
Make a graphics class that has a void called paintComponent and extends JComponent
Have that paintComponent void have Graphics g as a parameter, then do Graphics2D g2d = (Graphics2D) g;
Add the Graphics class to my JFrame
I can't find anything wrong with this, so I'm a little confused.
My code is here:
public static void main(String[] args) {
DragonEscape game = new DragonEscape();
frame.setTitle(title);
frame.setSize(1000, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(new Graphicsa());
frame.add(game);
}
and
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
public class Graphicsa extends JComponent {
private static final long serialVersionUID = 1L;
public Graphics g;
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g.fillRect(0, 0, 1000, 500);
g.setColor(Color.gray);
g.fillRect(0, 0, 100, 100);
}
}
frame.add(new Graphicsa());
frame.add(game);
Only one component can be added to the CENTER of the BorderLayout of the JFrame. So your game component replaces the graphics component.
Read the Swing tutorial for Swing basics. There are sections on:
How to use BorderLayout
Custom Painting
that directly related to this question.
Also, why are you even trying to do graphics painting? If looks to me like you are just trying to paint the background a certain color. Just use the setBackground(...) method on your game component.

I follow the tutorial in oracle about JLayer but it doesn't work with this code

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class MyJLayer extends JFrame {
public static void main(String[] args) {
MyJLayer jlayer = new MyJLayer();
jlayer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
JButton button = new JButton("Debug Only.");
panel.add(button);
UI ui = new UI();
JLayer<JPanel> jLayer = new JLayer<JPanel>(panel, ui);
jlayer.add(jLayer);
jlayer.setSize(100, 100);
jlayer.setVisible(true);
}
}
class UI extends LayerUI<JPanel>{
public void paint(Graphics g, JPanel c){
super.paint(g, c);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .8f));
g2d.setColor(Color.BLUE);
g2d.fillRect(0, 0, c.getWidth(), c.getHeight());
g2d.dispose();
}
}
the panel doesn't display BLUE color at all, but I don't know why.
Could anyone help me out?
I just couldn't find out.
http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html
Your paint method doesn't override a superclass method, so it's not being called. Change the signature to:
public void paint(Graphics g, JComponent c)
... and add the #Override annotation so that in future, the compiler can find the problem for you...

Set Oval throwing error

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.

Categories

Resources