I'm trying to learn drawing with swing. I'm trying to create a circle and position it on a specific position in a JPanel. This is what I've come up with but it does not show any figure:
import java.awt.*;
import javax.swing.*;
public class Circles extends JPanel {
private static final long serialVersionUID = 1L;
public Circles(){
setBackground(Color.white);
setPreferredSize(new Dimension(300, 300));
}
public void paintComponent(Graphics g){
super.paintComponents(g);
g.setColor(Color.black);
g.drawRect(10, 10, 50, 50);
}
}
This is the class that starts the program.
import java.awt.*;
import javax.swing.*;
public class StartCircles extends JFrame{
private static final long serialVersionUID = 1L;
private Circles circle;
public StartCircles(){
Container c = getContentPane();
circle = new Circles();
c.setBackground(Color.white);
c.setLayout(new FlowLayout());
setSize(300, 300);
c.add(circle);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args){
StartCircles c1 = new StartCircles();
}
}
What am I doing wrong? How do I position the figure where I want?
Try this SSCCE - noting the comments in the source.
import java.awt.*;
import javax.swing.*;
public class StartCircles extends JFrame{
private static final long serialVersionUID = 1L;
private Circles circle;
public StartCircles(){
Container c = getContentPane();
circle = new Circles();
c.setBackground(Color.white);
c.setLayout(new FlowLayout());
//setSize(300, 300);
c.add(circle);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack(); // size the GUI to the components within it
}
public static void main(String[] args){
StartCircles c1 = new StartCircles();
}
}
class Circles extends JPanel {
private static final long serialVersionUID = 1L;
public Circles(){
setBackground(Color.white);
setPreferredSize(new Dimension(300, 300));
}
public void paintComponent(Graphics g){
//super.paintComponents(g); // WRONG METHOD!
super.paintComponent(g);
g.setColor(Color.black);
g.drawRect(10, 10, 50, 50);
}
}
Your code running perfectly, but you are drawing Rectangle here.
so if you want to draw circle, you have to use
one of below methods
g.fillOval(10, 10, 50, 50);
g.drawOval(10, 10, 50, 50);
g.drawRect(10, 10, 50, 50); is sure to get you a rectangle. You need to look at the documentation for how to draw a circle.
You need to draw it using drawOval(). It takes 4 parameters:
x - the x coordinate of the upper left corner of the oval to be drawn.
y - the y coordinate of the upper left corner of the oval to be drawn.
width - the width of the oval to be drawn.
height - the height of the oval to be drawn.
So, replace your drawRect() with drawOval()
Related
This question already has answers here:
paintComponent not painting onto JPanel
(2 answers)
Closed 5 years ago.
I'm making a game in Java and first I didn't use a JPanel which caused flickering on repaint() and so I decided to use it. I'm not sure how to implement it in my current code. When I tried to do so all I got was a window that was as small as it gets. My original Window class code:
public class Window extends JFrame {
private double stepLen;
public Window(double stepLen) {
this.stepLen = stepLen;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
this.setLocation(x, y);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
add(goal);
goal.setBounds(325, -10, 600, 50);
setFocusable(true);
requestFocusInWindow();
this.setVisible(true);
}
This code works and it creates a window.
Main class:
Window window = new Window(50);
And then I tried to do it this way:
I have separate GameFrame (JFrame) and GameCanvas (JPanel) classes.
The Frame looks like this:
public class GameFrame extends JFrame{
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
this.setLayout(null);
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int x = (dim.width - this.getSize().width)/2;
int y = (dim.height - this.getSize().height)/2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
this.setLocation(x, y);
}
}
}
And the GameCanvas class
public class GameCanvas extends JPanel {
public GameCanvas() {
setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
goal.setBounds(325, -10, 600, 50);
this.getPreferredSize();
this.setVisible(true);
this.repaint();
}
Camickr is correct - go up vote and mark his answer as correct, this is only here to save him from pulling out what little hair he has remaining
You're using a null layout, without taking over its responsibility
Failed to provide sizing hints to for the component to allow the layout manager (which you're no longer using) to do it's job
This are all common mistakes, to which there are countless answers already provided
GameFrame
public class GameFrame extends JFrame {
private double stepLen;
public GameFrame() {
this.stepLen = 50;
this.setSize(800, 600);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setResizable(false);
this.setTitle("Frogger");
// Well, there's your problem...
//this.setLayout(null);
// Don't do this here...
this.setVisible(true);
this.getContentPane().setBackground(Color.black);
// Simpler way to achieve this
//Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
//int x = (dim.width - this.getSize().width) / 2;
//int y = (dim.height - this.getSize().height) / 2;
GameCanvas gcanvas = new GameCanvas();
this.add(gcanvas);
this.pack();
//this.setLocation(x, y);
setLocationRelativeTo(null);
setVisible(true);
}
}
GameCanvas
public class GameCanvas extends JPanel {
public GameCanvas() {
// Pointless
//setDoubleBuffered(true);
JLabel goal = new JLabel();
goal.setText("|=========|");
goal.setForeground(Color.WHITE);
goal.setFont(new Font("Seif", Font.PLAIN, 20));
this.add(goal);
// Pointless
//goal.setBounds(325, -10, 600, 50);
// Pointless
//this.getPreferredSize();
// Pointless
//this.setVisible(true);
// Pointless
//this.repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
public void paintComponent(Graphics g) {
int firstRoad = 5;
int i = 0;
int max = 10;
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g2);
g2.setColor(Color.WHITE);
g2.drawRect(5, 30, 75, 40);
while (i < max) {
g2.setColor(Color.WHITE);
g2.setStroke(new BasicStroke(3));
if (i % 2 == 0) {
g.setColor(Color.WHITE);
g.drawRect(3, firstRoad + 50 * i, 793, 50);
//g.fillRect(3, firstRoad + 50 * i, 793, 50);
} else {
g2.setColor(Color.WHITE);
g2.drawRect(3, firstRoad + 50 * i, 793, 50);
}
i++;
}
}
}
So, the way I was taught in my AP Computer Science class is to set your frame size and other frame characteristics in your main. Here is an example:
import javax.swing.JFrame;
public class theSetupClass{
public static void main(String[] args){
JFrame theGUI = new JFrame();
theGUI.setSize(300,400); //Sets the frame size to 300 by 400
theGUI.setTitle("Example");
theGUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theComponentClass component = new theComponentClass(); //Create new theComponentClass
frame.add(component);//Add theComponentClass to theGUI
frame.setVisible(true);
}
}
The code above creates the JFrame and adds the following class to it.
import java.awt.*;
import javax.swing.*;
public class theComponentClass extends JComponent{
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
Rectangle r = new Rectangle(10,10,this.getWidth()-10,this.getHeight()-10);
//Creates a rectangle that is 10 pixels away from all sides of the frame
g2.fill(r); //Draws and fills the rectangle
}
}
I hope that you find this helpful!
I was trying to draw simple shapes on a canvas in java (using Eclipse). The canvas appears of the right size and color. The shapes however appear only for a second and then disappear. When they appear they have the correct size, color and location, but they disappear after a second or so. It seems that a line is missing from the below code I wrote, but I can't figure out what it is.
import java.awt.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
/**
* Draws simple shapes
*/
public class SimpleDraw2 {
private JFrame frame;
private static Canvas canvas;
private Container contentPane;
private static Graphics graphics;
private Ellipse2D.Double circle;
/**
* Constructor
* Creates canvas and frame
*/
public SimpleDraw2() {
frame = new JFrame("Draw picture");
contentPane = frame.getContentPane();
canvas = new Canvas();
canvas.setSize(250, 250);
canvas.setBackground(Color.YELLOW);
canvas.setForeground(Color.BLUE);
contentPane.add(canvas);
frame.pack();
frame.setVisible(true);
}//end constructor
/**
* Draws two circles
* #param g
*/
public void paint(Graphics g){
circle = new Ellipse2D.Double(125, 125, 50, 50);
g = canvas.getGraphics();
if(g != null){
((Graphics2D) g).fill(circle);
g.setColor(Color.GREEN);
g.fillOval(0, 0, 50, 50);
}
}//end method
/**
* #param args
*/
public static void main(String[] args) {
SimpleDraw2 draw = new SimpleDraw2();
draw.paint(graphics);
}//end main
}//end class
Ah... in the SimpleDraw2.paint() method you get the canvas and then call its paint() method.
You should not do that. Ignore SimpleDraw2.paint() and instead post your paint code inside the canvas.paint() method. This way it will get drawn properly.
Painintg to canvas inside SimpleDraw2.paint() will in fact draw to the canvas, but as soon as that repaints itself, all shapes will be cleared.
Btw dont call paint(Graphics) directly, as you do it in the main() method, rather call repaint()
[UPDATED]
Oh almost forgot... usually you should put your code into the paintComponent() method. See the four test classes.
In v1, the canvas object you create is drawn above the paintings. I don't exactly know what content pane drawing changes in the drawing cycle, along with painting child components, and/or layout managers. That might be one of the reasons why, even though we don't call super.paint(), the canvas still gets painted.
V2 (and v4) gives you maximum control over your paint cycle, and using double/multiple buffering gets a lot easier this way.
V3 is easiest, just straight painting to the main frame, not having any variables or special magic.
In v4, you can also interface that callback(s). Gives you good control and is quite simple too.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Double;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class GraphicsPaint {
public static void main(final String[] args) {
new SimpleDraw2v1();
new SimpleDraw2v2();
new SimpleDraw2v3();
new SimpleDraw2v4();
}
}
class SimpleDraw2v1 {
private final JFrame frame;
private static Canvas canvas;
private final Container contentPane;
private static Graphics graphics;
private Ellipse2D.Double circle;
/**
* Constructor
* Creates canvas and frame
*/
public SimpleDraw2v1() {
frame = new JFrame("Draw picture");
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // important
contentPane = frame.getContentPane();
canvas = new Canvas();
canvas.setSize(250, 250);
canvas.setBackground(Color.YELLOW);
canvas.setForeground(Color.BLUE);
contentPane.add(canvas);
frame.pack();
frame.setVisible(true);
}//end constructor
/**
* Draws two circles
* #param g
*/
public void paint(final Graphics g) {
circle = new Ellipse2D.Double(125, 125, 50, 50);
final Graphics2D g2 = ((Graphics2D) g);
g2.fill(circle);
g2.setColor(Color.GREEN);
g2.fillOval(0, 0, 50, 50);
}//end method
}//end class
class SimpleDraw2v2 extends JFrame {
private static final long serialVersionUID = 2057752114790427629L;
public SimpleDraw2v2() {
setTitle("Painting v2");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setContentPane(new MyDrawPanel());
setBounds(200, 200, 800, 600);
setVisible(true);
}
}
class MyDrawPanel extends JPanel {
private static final long serialVersionUID = 6483380689207640805L;
#Override public void paint(final Graphics pG) {
// this call (or not overwriting paint() in the first place) results in
super.paint(pG);
// these three calls, in this order. you can test it
// paintComponent(pG);
// paintBorder(pG);
// paintChildren(pG);
final Double circle = new Ellipse2D.Double(125, 125, 50, 50);
final Graphics2D g2 = ((Graphics2D) pG);
g2.fill(circle);
g2.setColor(Color.GREEN);
g2.fillOval(0, 0, 50, 50);
}
#Override protected void paintComponent(final Graphics pG) {
System.out.println("MyDrawPanel.paintComponent()");
super.paintComponent(pG);
}
#Override protected void paintBorder(final Graphics pG) {
System.out.println("MyDrawPanel.paintBorder()");
super.paintBorder(pG);
}
#Override protected void paintChildren(final Graphics pG) {
System.out.println("MyDrawPanel.paintChildren()");
super.paintChildren(pG);
}
}
class SimpleDraw2v3 extends JFrame {
private static final long serialVersionUID = 2057752114790427629L;
public SimpleDraw2v3() {
setTitle("Painting v3");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setBounds(200, 200, 800, 600);
setVisible(true);
}
#Override public void paint(final Graphics pG) {
super.paint(pG);
final Double circle = new Ellipse2D.Double(125, 125, 50, 50);
final Graphics2D g2 = ((Graphics2D) pG);
g2.fill(circle);
g2.setColor(Color.GREEN);
g2.fillOval(0, 0, 50, 50);
}
}
class SimpleDraw2v4 extends JFrame {
private static final long serialVersionUID = 2057752114790427629L;
public SimpleDraw2v4() {
setTitle("Painting v4");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setContentPane(new JPanel() {
private static final long serialVersionUID = -8011251549484904282L;
#Override public void paint(final Graphics pG) {
super.paint(pG);
paintShapes((Graphics2D) pG); // use this call
}
#Override protected void paintComponent(Graphics pG) {
super.paintComponent(pG);
paintShapes((Graphics2D) pG); // or this call
}
});
setBounds(200, 200, 800, 600);
setVisible(true);
}
protected void paintShapes(final Graphics2D pG) {
final Double circle = new Ellipse2D.Double(125, 125, 50, 50);
pG.fill(circle);
pG.setColor(Color.GREEN);
pG.fillOval(0, 0, 50, 50);
}
#Override public void paint(final Graphics pG) {
super.paint(pG);
}
}
Thanks, Jay! Versions 2 to 4 work well. Version 1 still gave blank canvas. Took me a while to figure it out, but eventually I got it working. Turns out I should have used overridden update() instead of paint(). So here is the code that puts ellipses with coordinates and height width chosen by input into the yellow canvas:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Ellipse2D;
import java.util.Scanner;
/**
* Draws simple shapes
*/
public class SimpleDraw5 {
private Frame frame;
private static MyCanvas canvas;
private static Graphics graphics;
private Panel panel;
Ellipse2D.Double circle;
/**
* Draws blue ellipses on yellow canvas
* #param args
*/
public static void main(String[] args) {
SimpleDraw5 draw = new SimpleDraw5();
Scanner scan = new Scanner(System.in);
draw.addShapes();
int test;
boolean exit = false;
while (exit == false){
System.out.println("Draw another?");
System.out.println("Enter 1 to keep drawing, 2 to close window "
+ "3 to stop but keep window open>");
test = scan.nextInt();
if(test == 1){
draw.addShapes();
}
else if (test == 2)
System.exit(0);
else
exit = true;
}
}//end main
/**
* Constructor
* Creates canvas and frame
*/
public SimpleDraw5() {
frame = new Frame("Draw picture");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
} } );
panel = new Panel();
frame.add(panel);
canvas = new MyCanvas();
panel.add(canvas);
frame.pack();
frame.setVisible(true);
}
public void addShapes(){
canvas.update(canvas.getGraphics());
frame.pack();
frame.setVisible(true);
}
/**
* Returns circle set with paramenters
* #param x - X coordinate
* #param y - Y coordinate
* #param height
* #param width
* #return - object of class Ellipse2D.Double
*/
public static Ellipse2D.Double getCircle(int x, int y, int height, int width){
Ellipse2D.Double circle = new Ellipse2D.Double(x,y,height, width);
return circle;
}//end method
/**
* Returns "default" circle
* #return - object of class Ellipse2D.Double
*/
public static Ellipse2D.Double getCircle(){
Ellipse2D.Double circle = new Ellipse2D.Double(0,0,50, 50);
return circle;
}//end method
/**
* Inner class- defines canvas
*
*/
class MyCanvas extends Canvas{
private static final long serialVersionUID = 1L;
private Ellipse2D.Double circle;
/**
* Constructor. Sets canvas size and colors
*/
public MyCanvas(){
setSize(250, 250);
setBackground(Color.YELLOW);
setForeground(Color.BLUE);
}//end
/* (non-Javadoc)
* #see java.awt.Canvas#paint(java.awt.Graphics)
*/
public void paint(Graphics g){
super.paint(g);
frame.setVisible(true);
}//end method
/* (non-Javadoc)
* #see java.awt.Canvas#update(java.awt.Graphics)
*/
public void update(Graphics g){
g = this.getGraphics();
g.setColor(Color.BLUE);
Scanner scan = new Scanner(System.in);
System.out.println("Enter x");
int x = scan.nextInt();
System.out.println("Enter y");
int y = scan.nextInt();
System.out.println("Enter w");
int w = scan.nextInt();
System.out.println("Enter h");
int h = scan.nextInt();
Ellipse2D.Double circle = getCircle(x,y,w,h);
((Graphics2D) g).fill(circle);
((Graphics2D) g).draw(circle);
graphics = g;
}//end method
}//end inner class
}//end class
The JFrame and JPanel show up, but the paintComponent method isn't drawing on the JPanel. I only see the JLabel, JTextField and JButton that I added but not what should be drawn on the JPanel.
update; question has been answered: The circles actually were being drawn to the JPanel but I got the coordinates wrong so they were being drawn outside of the frame.
JFrame class:
package h02;
import javax.swing.*;
public class Circles extends JFrame {
public Circles() {
// JFrame and its properties
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(100, 100);
frame.setTitle("Circles");
frame.add(new CirclesPanel());
frame.setVisible(true);
}
public static void main(String[] args) {
new Circles();
}
}
JPanel class:
package h02;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class CirclesPanel extends JPanel implements ActionListener {
// Fields
private JTextField enterDiameter;
private JButton drawButton;
private int diameter;
private final int Y = 470;
// making the panel
public CirclesPanel() {
enterDiameter = new JTextField("100", 5);
enterDiameter.addActionListener(this);
drawButton = new JButton("Teken");
drawButton.addActionListener(this);
add(new JLabel("Diameter"));
add(enterDiameter);
add(drawButton);
}
// find the diameter
public void findDiameter() {
int diameterString = Integer.parseInt(enterDiameter.getText());
diameter = diameterString;
}
// draw circles
public void paintComponent(Graphics g) {
super.paintComponent(g);
int centre = getWidth() / 2;
g.drawLine(30, Y, Y , Y);
g.setColor(Color.ORANGE);
g.fillOval(centre, Y, diameter, diameter);
g.setColor(Color.BLACK);
g.drawOval(centre, Y, diameter, diameter);
g.drawOval(centre, Y, diameter / 2, diameter);
}
// on action performed...
public void actionPerformed(ActionEvent e) {
findDiameter();
repaint();
}
}
The problem is with your "Y" in CirclesPanel. Elements are drawn but outside the frame, try reducing Y, than surely you'll see your elements.
Alternatively increase the frame size.
I'm doing some exercise to understand Java and Swing API. Why do I have a nullPointerException in the Disegno constructor? I want to print the coordinates of the two rectangles, but they seem not to be initialitied.
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Disegno extends JFrame{
Disegno(){
this.setSize(500, 500);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.setContentPane(aba);
this.setVisible(true);
System.out.println(aba.rect.blue.x + "-" + aba.rect.blue.y);
System.out.println(aba.rect.yellow.x + "-" + aba.rect.yellow.y);
}
public static void main(String[] args){
new Disegno();
}
}
class MyPanel extends JPanel{
JPanel up, down;
RectArea rect;
MyPanel(){
this.setLayout(new BorderLayout());
up = new JPanel();
this.add(up, BorderLayout.NORTH);
up.setBackground(Color.red);
up.setVisible(true);
down = new JPanel();
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
down.setVisible(true);
rect = new RectArea();
this.add(rect, BorderLayout.CENTER);
this.setVisible(true);
}
}
class RectArea extends JPanel{
Rectangle blue, yellow;
boolean check = false;
RectArea(){
super();
this.setVisible(true);
}
public void initRect(){
blue = new Rectangle(0, 0, 100, 100);
yellow = new Rectangle(this.getWidth(), this.getHeight(), 100, 100);
System.out.println("ok");
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(check == false){
this.initRect();
check = true;
}
System.out.println(this.getWidth() + "-" + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
g.fillRect(yellow.x - yellow.width, yellow.y - yellow.height, yellow.width, yellow.height);
}
}
Others have helpfully suggested ways to detect and avoid the NullPointerException. Unfortunately, you can't rely on when your implementation of paintComponent() will be called. Instead,
Determine the required geometry as a function of the current widow's size; resize the window in the example below to see how yellow seems to stick to the bottom right corner.
Because MyPanel contains no components of its own, you should override getPreferredSize(), as #nIcE cOw shows here.
Use pack() to size the enclosing Window.
Build on the event dispatch thread.
Addendum: I can't understand why you override the method getPreferredSize().
Subclasses of JComponent override getPreferredSize() so that pack() can size the Window "to fit the preferred size and layouts of its subcomponents." That way you don't have to worry if the user has a different font, for example. MyPanel just draws geometric shapes, so you're the boss on preferred size. As discussed here, a demo may use setPreferredSize() for convenience, but you should understand the limitations of doing so.
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/q/11376272/230513
*/
public class Disegno extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Disegno();
}
});
}
Disegno() {
this.setSize(500, 500);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.add(aba);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
class MyPanel extends JPanel {
private JPanel up, down;
private RectArea rect;
MyPanel() {
super(new BorderLayout());
up = new JPanel();
up.setBackground(Color.red);
this.add(up, BorderLayout.NORTH);
rect = new RectArea();
this.add(rect, BorderLayout.CENTER);
down = new JPanel();
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}
class RectArea extends JPanel {
private Rectangle blue = new Rectangle(0, 0, 100, 100);
private Rectangle yellow = new Rectangle(0, 0, 100, 100);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(this.getWidth() + " x " + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
int dx = getWidth() - yellow.width;
int dy = getHeight() - yellow.height;
g.fillRect(dx, dy, yellow.width, yellow.height);
}
}
}
You never called rect.initRect(); anywhere, that's why you getting error related to NullPointerException at those System.out.println() lines. Why you using panelObject.setVisible(true) inside each class, first add them to the JPanel and simply call setVisible(...) on the JFrame that will do. Here watch your modified code with the said thingies, working as expected :
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Disegno extends JFrame{
Disegno(){
this.setSize(500, 500);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.setContentPane(aba);
this.setVisible(true);
System.out.println(aba.rect.blue.x + "-" + aba.rect.blue.y);
System.out.println(aba.rect.yellow.x + "-" + aba.rect.yellow.y);
}
public static void main(String[] args){
new Disegno();
}
}
class MyPanel extends JPanel{
JPanel up, down;
RectArea rect;
MyPanel(){
this.setLayout(new BorderLayout());
up = new JPanel();
this.add(up, BorderLayout.NORTH);
up.setOpaque(true);
up.setBackground(Color.red);
down = new JPanel();
down.setOpaque(true);
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
rect = new RectArea();
rect.initRect();
this.add(rect, BorderLayout.CENTER);
}
}
class RectArea extends JPanel{
Rectangle blue, yellow;
boolean check = false;
RectArea(){
super();
setOpaque(true);
}
public void initRect(){
blue = new Rectangle(0, 0, 100, 100);
yellow = new Rectangle(this.getWidth(), this.getHeight(), 100, 100);
System.out.println("ok");
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(check == false){
this.initRect();
check = true;
}
System.out.println(this.getWidth() + "-" + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
g.fillRect(yellow.x - yellow.width, yellow.y - yellow.height, yellow.width, yellow.height);
}
}
If you would write a System.out.println() inside the intiRect() you will know, the lines which are giving you errors are being called before the paintComponent(...) method itself. So it appears to me, that you have to take that logic out of the paintComponent(...) method and keep it somewhere else, or else remove those lines, if you don't need them.
You are trying to access aba.rect.blue and aba.rect.yellow in your Disegno constructor, however these are not initialized until RectArea.paintComponent is called, so it throws an NPE.
Are you sure that your code gave a NullPointerException .......??
Because when i ran your code, it worked fine...
Output:
ok
484-442
I have a JScrollPane and on top of it I have a JPanel named 'panel1'.
I want some rectangles to be drawn on this JPanel.
I have a class named DrawRectPanel which extends JPanel and does all the drawing stuff.
The problem is that, I tried to draw the rectangles on panel1 by writing the following code :
panel1.add(new DrawRectPanel());
but nothing appeared on panel1
then I tried, just as a test to the class DrawRectPanel :
JFrame frame = new JFrame();
frame.setSize(1000, 500);
Container contentPane = frame.getContentPane();
contentPane.add(new DrawRectPanel());
frame.show();
This worked, and produced the drawings but on a separate JFrame
How can I draw the rectangles on panel1 ?
Thanks in advance.
EDIT :
code for DrawRectPanel
public class DrawRectPanel extends JPanel {
DrawRectPanel() {
Dimension g = new Dimension(400,400);
this.setPreferredSize(g);
System.out.println("label 1");
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("label 2");
g.setColor(Color.red);
g.fillRect(20, 10, 80, 30);
}
}
only label 1 is printed on the screen
still no idea,
for example
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class CustomComponent extends JFrame {
private static final long serialVersionUID = 1L;
public CustomComponent() {
setTitle("Custom Component Graphics2D");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void display() {
add(new CustomComponents());
pack();
// enforces the minimum size of both frame and component
setMinimumSize(getSize());
setVisible(true);
}
public static void main(String[] args) {
CustomComponent main = new CustomComponent();
main.display();
}
}
class CustomComponents extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public Dimension getMinimumSize() {
return new Dimension(100, 100);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
#Override
public void paintComponent(Graphics g) {
int margin = 10;
Dimension dim = getSize();
super.paintComponent(g);
g.setColor(Color.red);
g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
}
}
instead of adding
contentPane.add(new DrawRectPanel());
you should do
contentPane.add(panel1);
Because you already have new DrawRectPanel in panel1. But in your code you are adding another instance of DrawRectPanel in contentPane. And never added panel1 in none of your container.
to fix your problem, change "paintComponent" to "paint" when the window repaints automatically, it should work.