I am aware this is my error. My question is why isn't this working what am i missing i can call this is i put it a method instead of a class so i am assuming theirs something wrong with the third class?
Class 1:
package assignment.pkg1.java;
import java.awt.Color;
import javax.swing.JFrame;
public class JVMVeiwer {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
final int FRAME_WIDTH = 1000; // Frame Width
final int FRAME_HEIGHT = 800; // Frame Height
JFrame frame = new JFrame();
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT); //Sets Frame Size
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("JVM Diagram");// Sets the Title
JVMComponent component = new JVMComponent();
frame.setBackground(Color.WHITE);
frame.add(component); // adds the diagram to the JFrame
frame.setVisible(true); // Makes the frame visible
}
}
Class 2:
package assignment.pkg1.java;
import java.awt.*;
import javax.swing.JComponent;
public class JVMComponent extends JComponent {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g; // recover the graphic
JVMDiagram diagram = new JVMDiagram(); // creates an instance of JVM Diagram
diagram.draw(g2);
}
}
Class 3 this is the one i i cant use o paint to the jframe:
package assignment.pkg1.java;
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JComponent;
public class JVMDiagram {
// Constructor
public JVMDiagram() {
}
// Draw method for shape
public void draw(Graphics2D g2) {
// Detailed instructions to draw shape
int x = getWidth();
int y = getHeight();
int temp, temp2;
int width = x / 2;
int height = x / 2;
x = (x - width) / 2;
y= (y - height) / 2;
g2.setColor(Color.RED);
g2.drawOval(x, y, width, height);
g2.drawRect(x, y, width, height);
g2.setColor(Color.RED);
g2.drawLine(x, y, width + x, height + y);
g2.drawRoundRect(x, y, width, height, y, y);
g2.drawLine(x + width, y, x, height + y);
}
}
Your problem is that you're misusing inheritance. Your JVMDiagram is extending JVMComponent and it shouldn't. Yes, you gain JVMComponent's getWidth() and getHeight() method, but they don't mean anything since JVMDiagram isn't being added to the GUI as a component, shouldn't be added as a component, and it has 0 height and width (print them out).
Rethink your design, don't use inheritance for this. Instead pass in values from one object to the other if needed. For instance, create a JVMDiagram field within JVMComponent and initialize it. Pass in the width and height with the Graphics2D in the JVMDiagram draw method in JVMComponent's paintComponent method.
Side issue: never call repaint() from within a painting method or from code that is called from within a painting method.
Related
So I've been stuck on this problem for a while now and I'm desperate for help. Please help me. I've got 3 classes:
Circle is just suppose to draw a circle in the frame created by Frame with random starting position (and defind the radius).
Frame is the mainclass with methods such as addCircle(), bounce(), start(), stop(), run() (moves the circles) and quit(). This class also creates the frame in which the circles are added to.
Interfa is just for now a inteface frame where I define the radius, number of circles and Frame size.
No matter what I try I cannot add more than two circle (one is colored and one is not):
The "recursive way":
private static void addCircle(int n){
Circle[] circles = new Circle[n+10];
if (n > 0){
circles[circleAdd] = new Circle();
frame.add(circles[circleAdd]);
circleAdd = circleAdd + 1;
addCircle(n-1);
}
}
Normal itterative way
private static void addCircles(int n){
ArrayList<Circle> circles = new ArrayList<Circle>();
for(int i = 0; i<=n;i++){
circles.add(new Circle());
frame.add(circles.get(i));
}
}
This is how I create my Frame:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public Class Frame{
private static JFrame frame;
private static int circleAdd = 0;
private static JPanel fra;
public static void mainFrame(){
frame = new JFrame();
frame.setSize(500,500);
frame.setVisible(true);
fra = new JPanel();
frame.add(fra);
...
//addCircle and addCircles
...
public static void main..
}
}
This is my circle:
import java.awt.*;
import javax.swing.*;
import java.util.Random;
public class Circle extends JPanel{
private Random random = new Random();
public void paint(Graphics g){
int randX = random.nextInt(250)+50;
int randY = random.nextInt(250)+50;
g.drawOval(randX,randY,50,50);
g.setColor(Color.ORANGE);
g.fillOval(100,100,50,50);
}
}
I would suggest that your general approach is wrong. Instead of using a JPanel as the element, you should have a JPanel capable of painting any number of "circles". The Graphics2D API is capable of drawing complex shapes (including ovals).
The main issues I can see are:
JFrame by default is using a BorderLayout, this only allows a single component to be placed in each of the five available positions
Layout managers rely on the preferred/minimum/maximumSize hints to make determinations about the size of the components. They are also responsible for deciding on where the component should be placed. In your current implementation, this would mean that it's possible for you to paint beyond the visible range of the component
Overriding paint is not recommend, and failing to call super.paint could cause a number of unexpected and difficult to diagnose issues
Painting can occur at any time, so using random values in the paint method will cause the UI to constantly change
Instead, you could define your own Circle class which takes the location and size you want and simply acts as a container
public class Circle {
private int x;
private int y;
private int radius;
private Ellipse2D shape;
public Circle(int x, int y, int radius) {
this.x = x;
this.y = y;
this.radius = radius;
this.shape = new Ellipse2D.Double(x, y, radius * 2, radius * 2);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getRadius() {
return radius;
}
public Rectangle getBounds() {
return shape.getBounds();
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.ORANGE);
g2d.fill(shape);
}
}
This is simply a container class, it represents the information need to generate the desired outcome. It has a convince method which is capable of then painting the shape itself.
You would then need to create a List of these shapes and paint them to your component
public class TestPane extends JPanel {
private List<Circle> circles = new ArrayList<>(10);
private Dimension size;
public TestPane() {
Random random = new Random();
int maxX = 0;
int maxY = 0;
for (int index = 0; index < 10; index++) {
int randX = random.nextInt(250) + 50;
int randY = random.nextInt(250) + 50;
circles.add(new Circle(randX, randY, 25));
maxX = Math.max(maxX, randX + 50);
maxY = Math.max(maxY, randY + 50);
}
size = new Dimension(maxX, maxY);
}
#Override
public Dimension getPreferredSize() {
return size;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Circle circle : circles) {
Graphics2D g2d = (Graphics2D) g.create();
circle.paint(g2d);
g2d.dispose();
}
}
}
One of the things you seem to lack understanding in is how painting actually works in Swing.
Start by having a look at Performing Custom Painting and Painting in AWT and Swing for more details.
A deeper understanding of how layout managers and the component hierarchy work also wouldn't hurt
I am writing a program which involves creating a JFrame and drawing a circle inside it using drawOval() from the Graphics class. I have reached a problem where I am trying to create a point at the centre of the JFrame, and then draw my circle with this pont being the x and y coordinates of the circle. Here is my code so far:
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.Point;
class MouseJFrameMotion extends JFrame implements MouseMotionListener{
int circleXcenter;
int circleYcenter;
int circleRadius = 50;
boolean show = false;
public MouseJFrameMotion(){
addMouseMotionListener(this);
}
public void paint(Graphics g){
super.paint(g);
if(show){
g.drawOval(circleXcenter,circleYcenter, circleRadius*2,circleRadius*2);
}
}
public void mouseDragged(MouseEvent e){
}
Point frameCenter = new Point((this.getWidth()/2), (this.getHeight()/2));
public void mouseMoved(MouseEvent e){
int xLocation = e.getX();
int yLocation = e.getY();
show = true;
circleXcenter = (int) frameCenter.getX();
circleYcenter = (int) frameCenter.getY();
repaint();
}
}
public class GrowingCircle {
public static void main(String[] args) {
MouseJFrameMotion myMouseJFrame = new MouseJFrameMotion();
myMouseJFrame.setSize(500, 500);
myMouseJFrame.setVisible(true);
}
}
As you can see in the main() function, I set the size of the JFrame to 500x500. However, when the circle is drawn, it's x and y coordinates are (0,0) when I expect them to be (250, 250) based on Point frameCenter after repaint() is called. Where am I going wrong?
So two things...
Don't override paint of JFrame, there a JRootPane, contentPane and other components between the user and the frames surface which can interfere with the painting. Instead, use a JPanel and override its paintComponent method
At the time Point frameCenter = new Point((this.getWidth()/2), (this.getHeight()/2)); is evaluated, the frame's size is 0x0, you need to reevaluate the frameCenter before you paint the circle. When you do this will depend on how dynamic you want the change to be
I think you need both repaint() and revalidate() method
When you are constructing the class MouseJFrameMotion, the variable frameCenter is defined and set width and height 0 and it will never change. So what you can do is to calculate the frame center when you are drawing.
public void mouseMoved(MouseEvent e) {
int xLocation = e.getX();
int yLocation = e.getY();
show = true;
Point frameCenter = new Point((this.getWidth() / 2), (this.getHeight() / 2));
circleXcenter = (int) frameCenter.getX();
circleYcenter = (int) frameCenter.getY();
repaint();
}
I have a problem to create circle whenever I like to call the paint function it will draw me another circle. Here is my code:
import java.awt.*;
import javax.swing.*;
public class MyOnto extends JFrame
{
int weight = 960;
int heigh = 960;
int x = 200;
int y = 100;
//Graphics p;
private static MyOnto my = new MyOnto();
public MyOnto()
{
setTitle("My Ontology");
setSize(weight, heigh);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(Color.black);
drawing(g,x,y,100,50); //g, x ,y, w, h of circle
}
public void drawing(Graphics g, int x, int y, int w, int h)
{
g.drawOval(x,y,w,h);
g.drawString("Helo", x+25,y+20);
x = x + 100;
y = y + 100;
}
public static void main(String[] args)
{
//my = new MyOnto();
my.paint(null);
my.paint(null); //try to print one more circle
}
}
The output is always just one circle. How can I make it like a function call whenever I want to draw extra one circle it will just a simple call a function?
Don't override paint() on a JFrame.
Custom painting is done by override paintComponent(...) on a JPanel and then you add the panel to the frame.
it will draw me another circle.
There are two common approaches:
Keep a List of circles to draw
Draw the circles on a BufferedImage
Check out Custom Painting Approaches for working examples of both approaches.
For this program I'm required to recursively draw a 'pagoda', which is a series of diminishing rectangles, aligned centrally, stacked on top of each other. I think I've gotten the logic behind the actual figure, but I'm having trouble figuring out how to actually get the figure drawn as Rectangles with Graphics2D. I tried to shoehorn it into a basic shape drawing program and couldn't find out how to work recursion into it.
This is the code that I've written to this point, without taking graphics into account:
import java.awt.Rectangle;
public class PagodaDrawer
{
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
public PagodaDrawer(int initialY, int initialHeight, double scaleFactor)
{
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
}
public void drawPagoda()
{
drawLayer(0, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
return;
}
drawLayer(x - (((1 - scale)* x) / 2), y + (y * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
//Draw r?
}
}
How can I recursively draw layers of the figure in a frame?
EDIT:
For any interested, this is the final code
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PagodaDrawer extends JPanel
{
private int initialX;
private int initialY; //Top of the bottom rectangle
private int initialHeight; //Height for the bottom rectangle
private double scale; //Amount to reduce each layer
private boolean isRenderable;
private ArrayList<Rectangle> recs;
public PagodaDrawer(int initialX, int initialY, int initialHeight, double scaleFactor)
{
this.initialX = initialX;
this.initialY = initialY;
this.initialHeight = initialHeight;
scale = scaleFactor;
isRenderable = false;
recs = new ArrayList<Rectangle>();
}
public void drawPagoda()
{
drawLayer(initialX, initialY, 2 * initialHeight, initialHeight);
}
public void drawLayer(double x, double y, double width, double height)
{
if(y < 0 || height < 5) //If off the top of the screen, or less than 5 tall
{
isRenderable = true;
return;
}
drawLayer(x + .5 * (width - (width * scale)), y - (height * scale), width * scale, height * scale );
Rectangle r = new Rectangle((int)x, (int)y, (int)(2 * height), (int)height);
recs.add(r);
}
public void paintComponent(Graphics g)
{
if(!isRenderable)
return;
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for(int i = 0; i < recs.size(); i++)
{
g2.draw(recs.get(i));
System.out.println(recs.get(i));
}
}
}
Coupled with this JFrame:
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DisplayComponent extends JFrame
{
private static final long serialVersionUID = -4279682826771265863L;
private static final int FRAME_WIDTH = 500;
private static final int FRAME_HEIGHT = 500;
private JPanel panel;
private PagodaDrawer p;
public DisplayComponent(int initialHeight, double scaleFactor)
{
p = new PagodaDrawer(FRAME_WIDTH / 2, FRAME_HEIGHT, initialHeight, scaleFactor);
panel = new JPanel();
p.drawPagoda();
add(p);
pack();
setSize(FRAME_WIDTH, FRAME_HEIGHT);
setVisible(true);
}
}
Instead of making drawLayer() recursive, write a recursive createRectangle() that adds each new Rectangle instance to a List<Rectangle>. Render the list in your implementation of paintComponent(), illustrated here.
In Java AWT and Swing you draw with Graphics / Graphics2D methods.
Example: graphics.fillRect(x, y, w, h);
You should get the graphics(?:2d) object from the component where you want to draw into, usually the main Frame or some Component.
Calling your drawings within paintComponent() of the frame should work fine like this:
How to use paintComponent in Java to paint multiple things, but rotate one?
Here is the Java6 docs:
http://docs.oracle.com/javase/6/docs/api/
How do I draw the unique rectangle(cube) inside the oval:
http://i.stack.imgur.com/pmHTl.jpg
For me it is tricky to use graphics to draw a rectangle such as the one shown. Any advice on what to do.
Ok. I will try to make myself as clear as I can. What I have so far are the orange ovals and the slim gray oval that is behind it. I only need to create one of these "dots" in a class and i will make many objects of them. The Task I need help in is drawing the "rectangle" shape you see that is in the orange dot using J Component possibly. By request I will add a picture of what I have so far if this edit does not fulfill the need for you to understand my problem.
Thanks
Edit : Here is the Code that I have for creating the ovals if that is of interest to you-
public void paint(Graphics g) {
Color c = (Color.orange);
g.setColor(Color.gray);
g.fillOval(3,3,60,60);
g.setColor(c);
g.fillOval(0,0,60,60);
}
Edit: My Attempt at an SSCCE -->
NanoBot Class(Where I am Creating the Bot in paint)
/**
* #author (Omar Ahmed)
*/
import javax.swing.*;
import java.awt.*;
public class NanoBot extends Image
{
public NanoBot(int x, int y, int w, int h)
{
super(x,y,w,h);
}
public void paint(Graphics g) {
Color c = (Color.orange);
g.setColor(Color.gray);
g.fillOval(3,3,60,60);
g.setColor(c);
g.fillOval(0,0,60,60);
//g.setColor(Color.black);
//g.fillOval(10,20,10,10);
//g.fillOval(40,20,10,10);
}
}
And The Driver:
/** Bot Swarm
* Date: May, 2013
* Author: Omar Ahmed
*/
import java.awt.*;
import javax.swing.*;
public class Driver {
private JFrame win;
private NanoBot bot1;
public Driver() {
win = new JFrame(" Swarm ");
win.setLayout(null);
win.setVisible(true);
win.setBounds( 20, 20, 800, 700);
win.getContentPane().setBackground(Color.white);
bot1=new NanoBot(50,50,70,70);
win.add(bot1,0);
}
Hope This Helps
Your first step is to break down your requirements...
You need to draw 3 shapes, front, top, side.
The front's y position is offset by 0.412 of the overall height. It's width is 0.77 of the overall width.
The top's height is 0.412 of the overall height, and it has a horizontal inset of 0.2 of the overall width...
The side's x position is offset by 0.77 of the overall width and has an inset of 0.47 of the over all width.
This is all very important, as you want to ensure that the shapes can resize reasonably well...
Now, you could simply use Graphics#drawLine and Graphics#drawRectangle to build the shape, but that, to me, is a lot of work...
Instead the 2D Graphics is very powerful and contains many wonderful things, the one of interest today is the Shape API, which allows you to define many different shapes, which can be drawn or filled.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestChip {
public static void main(String[] args) {
new TestChip();
}
public TestChip() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int width = 44;
int height = 17;
Front front = new Front(width, height);
Top top = new Top(width, height);
Side side = new Side(width, height);
draw(g2d, front, Color.BLACK, Color.YELLOW);
draw(g2d, top, Color.BLACK, Color.GRAY);
draw(g2d, side, Color.BLACK, Color.DARK_GRAY);
g2d.dispose();
}
protected void draw(Graphics2D g2d, Shape shape, Color foreground, Color background) {
g2d.setColor(background);
g2d.fill(shape);
g2d.setColor(foreground);
g2d.draw(shape);
}
}
public class Front extends Path2D.Float {
public Front(float width, float height) {
float frontWidth = width * 0.77f;
float yOffset = height * 0.412f;
moveTo(0, yOffset);
lineTo(frontWidth, yOffset);
lineTo(frontWidth, height);
lineTo(0, height);
closePath();
}
}
public class Side extends Path2D.Float {
public Side(float width, float height) {
float xOffset = width * 0.77f;
float inset = height * 0.47f;
moveTo(xOffset, inset);
lineTo(width, 0);
lineTo(width, inset);
lineTo(xOffset, height);
closePath();
}
}
public class Top extends Path2D.Float {
public Top(float width, float height) {
float inset = width * 0.2f;
float shapeHeight = height * 0.412f;
moveTo(inset, 0);
lineTo(width, 0);
lineTo(width - inset, shapeHeight);
lineTo(0, shapeHeight);
closePath();
}
}
}
Your job is to now go away, study the example, study the referenced tutorials, study the associated API docs and figure out how to align the above shape within you circle and draw it's legs...
A hint. Make a "Bug" class that knows how to renderer all this and simply translate the position of the Graphics as required...