Basically i'm starting to learn graphics in java so I made a simple program to display two rectangles and a string on the screen. The program compiles fine but does not display the two rectangles or the string. Any input on my problem would be greatly appreciated.
//ClassOne.java
import javax.swing.*;
public class ClassOne {
public static void main(String[] args)
{
JFrame f = new JFrame("Title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ClassTwo object = new ClassTwo();
f.add(object); //add object to frame
f.setSize(400,250);
f.setVisible(true);
}
}
//ClassTwo.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ClassTwo extends JPanel {
public void paintComponet(Graphics g) //takes an object from a graphics class
{
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(Color.WHITE);
g.fillRect(25, 25, 100, 30); //x,y,width, height
g.setColor(new Color(190,81,215));
g.fillRect(25, 70, 100, 30);
g.setColor(Color.RED);
g.drawString("Text", 25, 120);
System.out.print("hi");
}
}
It's
public void paintComponent(Graphics g)
not
public void paintComponet(Graphics g) {
Add the #Override annotation to allow the compiler to check for the method
Related
So I am trying to create a simple program that prints out a rectangle but I am having this problem and I don't know how to fix it. Here is my code:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class GraphicsEditor extends JPanel{
public void drawShape(Graphics g) {
super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
GraphicsEditor ga = new GraphicsEditor();
frame.setSize(1280, 720);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ga);
}
}
The error is when I am trying to add the super in here:
public void drawShape(Graphics g) {
super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
A JPanel has no drawShape(Graphics) method, so calling the 'super' method makes no sense. When you think you're overriding a method, be sure to add the #Override notation to get a compiler warning when the method is incorrectly spelled, uses the wrong arguments, or is just entirely non-existent (as is the case here).
The correct way to go about this is to override the paintComponent method, call the (existing) super method, then immediately call the drawShape method with the Graphics instance provided to the paintComponent method.
This is the result when the GUI is shrunk down:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
public class GraphicsEditor extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawShape(g);
}
// #Override // does NOT override an existing method!
public void drawShape(Graphics g) {
//super.drawShape(g);
g.setColor(Color.BLUE);
g.drawRect(100, 100, 120, 150);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
GraphicsEditor ga = new GraphicsEditor();
frame.setSize(280, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(ga);
}
}
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!
I have to draw an archery target with two black lines in the innermost circle that forms a cross, but every time i adjust the lines so that the lines are closer to the centre it goes behind the image instead of appearing on top. How can I stop this? Does it need to have a separate set of instructions entirely?
This is my code:
package sumshapes;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class SumShapes extends JFrame
implements ActionListener {
private JPanel panel;
public void paint(Graphics g)
{
g.setColor(Color.BLACK);
g.drawLine(250, 200, 250, 200);
g.drawOval(140,90,200,200);
g.setColor(Color.BLACK);
g.fillOval(140,90,200,200);
g.drawOval(162,109,155,155);
g.setColor(Color.BLUE);
g.fillOval(162,109,155,155);
g.drawOval(183,129,112,112);
g.setColor(Color.RED);
g.fillOval(183, 129, 112, 112);
g.drawOval(210,153,60,60);
g.setColor(Color.YELLOW);
g.fillOval(210, 153, 60, 60);
g.setColor(Color.BLACK);
}
public static void main(String[] args) {
SumShapes frame = new SumShapes();
frame.setSize(500,400);
frame.setBackground(Color.yellow);
frame.createGUI();
frame.setVisible(true);
}
private void createGUI(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container window = getContentPane();
window.setLayout (new FlowLayout());
}
public void actionPerformed(ActionEvent event) {
Graphics paper = panel.getGraphics();
paper.drawLine(20,80,120,80);
}
}
All your drawing should go into the paintComponent method of a lightweight component, such as a JPanel.
There should never be a need to call getGraphics. If you wish to change the drawing upon a particular action you should a) program the logic into paintComponent b) alter the logic in the Action c) call repaint on the Component
For example:
private JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);//call parent method first thing
//paint here
}
#Override
public Dimension getPreferredSize(){//provided so you can size this component as necessary
return new Dimension(500,400);
}
};
....
frame.add(panel);
frame.pack();
As an aside, I'd recommend placing all calls to to Swing components on the EDT - this means wrapping your Swing calls in the main method with SwingUtilities. eg
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable(){
#Override
public void run() {
SumShapes frame = new SumShapes();
....
}
});
}
public void paint(Graphics g){
g.setColor(Color.red);
g.drawString("hello",50,50);
}
the background of the frame looks strange and transparent.
This problem only happens when I draw a string, but when I draw a rectangle or any another shape, the frame looks good.
this is the code:
import javax.swing.*;
import java.awt.*;
public class B extends JFrame {
public B() {
this.setTitle("programme");
this.setSize(400, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.setVisible(true);
}
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawString("hello", 50, 50);
}
}
this is the result:
Thank you for helping .
I have found the answer.
The problem happened because I didn't pass the object (g) to the constructor in paint method
This is the whole code :
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
class B extends JFrame {
public B() {
this.setTitle("programme");
this.setSize(400,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new FlowLayout());
this.setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
// I have added the previous line and it solved the problem
g.setColor(Color.red);
g.drawString("hello", 50, 50);
}
}
public class main {
public static void main(String[] args) {
B obj = new B();
}
}
Anyway thank you for helping.
strange, at my place everythings works fine.
Try in constructor use:
super("programme");
instead setTitle("programme");
if doesn't work add
setBackground(Color.lightGray);
in constructor.
Anyway, when you want to paint String you should use JLabel class.
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);
}
}