I have the following task for my school in Java:
Create a GUI window with your own graphic. This graphic should be created in a separate JPanel class and drawn using the draw and fill methods of the java.awt.Graphics class (e.g. a house with a garden, a car, ...). The graphic should contain at least 5 different types of graphics (rectangle, oval, ...), at least one polygon (draw or fillPolygon (polygon p) method) and an arc (draw or fillArc method (int x, int y, int width, int height, int startAngle, int arcAngle)). The graphic should also contain at least 10 drawing elements and consist of at least 4 different colors.
But I don´t know how to use the class Graphics, so I don´t know how to create a Grahpics object and edit it. Does anyone know how to solve this? Thank you
You can use graphics with a JPanel;
class exampleclass extends JPanel {
exampleClass() {
...
}
#Override
public void paintComponent(Graphics g) {
...your code here...
}
}
For more information, look at; https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html
You can call paint method with, repaint();
Related
I am currently working on a test driven interactive 2D fluid dynamics simulation for my Bachelor thesis. The basic idea is that the user can draw shapes on his screen and the program will simulate how a fluid will flow around these shapes.
So far I have only started with the painting process and I have already run into a little problem.
First, here is a little UML diagram that shows my project structure so far
As you can see, I have created a Painter class that can visit several shapes and will call one of the abstract paint methods depending on the shape type. Then there is the SwingPainter class which inherits from the Painter class and implements the three paint methods as well as the clear method.
Here is the code for my SwingPainter:
public class SwingPainter extends Painter {
private final GraphicPanel graphicPanel;
public SwingPainter(GraphicPanel graphicPanel) {
this.graphicPanel = graphicPanel;
}
private Graphics getGraphics() {
return graphicPanel.getGraphics();
}
#Override
protected void paintLine(Point start, Point end) {
getGraphics().drawLine(start.getX(), start.getY(), end.getX(), end.getY());
}
#Override
protected void paintRectangle(Point start, Point end) {
int minX = start.getX() < end.getX() ? start.getX() : end.getX();
int minY = start.getY() < end.getY() ? start.getY() : end.getY();
int width = Math.abs(start.getX() - end.getX());
int height = Math.abs(start.getY() - end.getY());
getGraphics().drawRect(minX, minY, width, height);
}
#Override
protected void paintCircle(Point center, double radius) {
int minX = center.getX() - (int) radius;
int minY = center.getY() - (int) radius;
int diameter = (int) radius * 2;
getGraphics().drawOval(minX, minY, diameter, diameter);
}
#Override
public void clear() {
graphicPanel.paintComponent(getGraphics());
}
}
So my problem is that the GraphicPanelPresenter(see UML diagram) is responsible for passing the Painter/Visitor to the shapes when the user left clicks or moves the mouse(the second point of a line will follow the cursor for example). That means the actual painting is done outside of Swing's paint method. As a result I have encountered some flickering while painting and I was wondering if anyone knew how to fix that without throwing the whole painter/visitor functionality out the window(since there are other features concerning the shapes that still have to be implemented and could easily be handled by simply passing them another type of visitor).
Well, that was a rather lengthy description for a rather small problem, sorry for the wall of text, but I would be glad for any kind of hint!
You need to do all the of painting in the various Swing paint methods that are designed to be overridden for custom painting (such as paintComponent). Only Swing will know when it's done drawing, or when a new frame needs to be drawn to.
What it really seems like you need to do, is to have your GraphicsPanel have a reference to the object that holds your shape's states, and then draw the graphics that represent that state in paintComponent.
This should also simplify your class relationship diagram as well, since within GraphicsPanel you can call the state object's methods from your listeners to change the state (I would choose different names to make the state object not aware that the changes are based on UI interactions, so if right click rotates, make the method called rotate instead of handleRightClick).
I have a very simple problem. I am learning Java, and was given an assignment to draw a car. I did this all in one class that extends JPanel, and did the drawing within paintComponent().
I realize this is poor object-oriented programming, and decided to try to subclass some of the parts to rectify this situation.
I tried to create a class that draws wheels, but was unsuccessful.
Essentially, I wanted to be able to do this:
Main Class extends JPanel
paintComponent{
Wheel leftWheel = new Wheel(0, 50, 100);
this.add(leftWheel);
}
This should draw a wheel at the point (0, 50) within the JPanel, and have a diameter of 100.
However, i'm unsure how i'm supposed to control the positioning in the JPanel. When I do this, the wheel in drawn at the top center of my window. This is what my wheel class looks like:
public class Wheel extends JComponent {
private int x, y, diameter;
private boolean clockwise;
Wheel(int x, int y, int size, boolean cw)
{
this.setPreferredSize(new Dimension(size, size));
this.x = x;
this.y = y;
diameter = size;
clockwise = cw;
repaint();
}
public void paintComponent(Graphics canvas)
{
super.paintComponent(canvas);
canvas.setColor(Color.gray);
canvas.fillOval(x,y,diameter,diameter);
}
}
The x and y should be where it appears on the parent window, however, this is not the case in the following code (located in the parent class that extends JFrame):
Wheel leftWheel = new Wheel(0,0,WHEEL_DIAMETER,true);
this.add(leftWheel);
The wheel doesn't draw at the top left of my window, it draws in the center of my window at the top. Am I doing something incorrectly? Sorry if I don't follow some Java conventions, I don't have any experience yet. Is this how I should be handling the drawing of the wheel, or is there a more accepted practice for doing this type of drawing?
For example, in my JPanel class, if I add the following code:
Wheel x = new Wheel(50,60,75,true);
this.add(x);
I get a frame sized 75x75 in which a wheel (sized 75x75) is drawn at the point (50,60) within that frame, not within the parent JPanel's coordinate system. The result is a circle that gets clipped and I only see the top left of the circle. That image is displayed at the top center of my JPanel
I understand how to draw the wheel, and move it within itself, but how do I position the wheel on the JPanel??
Your constructor has a small bug,
Wheel(int x, int y, int size, boolean cw) {
this.setPreferredSize(new Dimension(size, size));
diameter = size;
clockwise = cw;
repaint();
}
You forgot to store x and y. I think you wanted,
Wheel(int x, int y, int size, boolean cw) {
this.x = x;
this.y = y;
this.setPreferredSize(new Dimension(size, size));
diameter = size;
clockwise = cw;
repaint();
}
Because your x and y are 0 if you don't set them.
Could you explain how to control it's location within the JPanel, not within itself please?
The default LayoutManager for a JPanel is a FlowLayout so the component will always be positioned based on the rules of the layout manager.
If you want to add components to a random location then you need to use a null layout. But when you use a null layout you are then responsible for setting the size and location of the component. So, in reality the custom painting should always be done at (0, 0) in your custom component.
Instead of adding multiple JPanels to create the vehicle I would simply use one class that extends JPanel and create multiple methods to create things such as wheels etc. to be called from within the overridden paintComponent method. You can pass the new method a reference of your graphics object, create a copy of your graphics object using g.create(), or use getGraphics() from inside the method itself. Inside the method to create a wheel you then are able to calculate it's position by using the panel's dimensions and place it properly.
An alternative would be to define and return shapes in other methods and simply draw them using the graphics object in paintComponent().
We've just learned how to create our own class, and this particular assignment we had to work with graphics. We had to draw a crayon, and then create a test program where there are 5 crayons lined up next to one another (so we just change the color and x,y of each one). I know how to change the color and x,y coords, but my question is...
how do I 'print' each crayon? Yes, it's an applet and yes I know I need a .html file. But what exactly goes in the test program in order for the crayon to show up when I run the .html file? I've run non-applets before in test programs using System.out.println, but never any graphics. Would it just be System.out.println(Crayon); ?
Also, how do I get multiple crayons? I'm assuming it's Crayon crayons = new Crayon;, and then the next one might be 'Crayon crayons2 = new Crayons;`? I'm not sure.
The x,y coordinates need to be modified w/each crayon, but the UML for the assignment told me not to make them instance variables but instead to put it in 'public void paint (Graphics g, int x, int y)'. What I have so far for the test program (may or may not be correct):
import javax.swing.JApplet;
import java.awt.*;
public class BoxOfCrayons extends JApplet {
Crayon first = new Crayon (Color.red, 50, 250)
Start by having a read through 2D Graphics.
Basically, you will need to create some kind of list of Cryons. This can either be a Collection or array, depending on what you know. I would personally use a ArrayList as it's flexible and easy to use, but doesn't suffer from the same constraints as an array.
Next, create you're self a custom component (ie BoxOfCryons) which extends from JPanel. Override this classes paintComponent method. Within this method, run through the list of Cryons and paint each one, incrementing the x offset by the width of the last Cryon.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = 0;
int y = 0;
for (Crayon crayon : cryons) {
crayon.paint(g2d, x, y);
x += crayon.getWidth();
}
g2d.dispose();
}
Create yourself a new class that extends from JApplet. In it's init method, set the applets layout manager to BorderLayout and add an instance of the BoxOfCryons class to it.
What I want to achieve is something like this:
public void paint(Graphics g) {
Graphics2D ga = (Graphics2D) g;
MyShape c = new MyShape();
ga.draw(c);
}
I want that MyShape class to contain the info required to draw a circle with a number inside it.
So, I guess I need to create some kind of container/component, and drew what I need (the circle and the number) inside it, and then pass it further to the method I've pasted above.
The problem is I don't know what class to extend ... and the rest of the story.
A Shape is just that: a shape. A circle is a shape. A rectangle is a shape. But a circle with a number inside it is not a shape. My guess is that you in fact want something like this:
public class CircleWithNumberInside extends JComponent {
#Override
protected void paintComponent(Graphics g) {
// TODO draw a circle, and draw a number inside it.
}
}
You can certainly implement the Shape interface yourself, but there's no need when you can use an existing subclass, such as Ellipse2D. Just construct it with the same value for width and height. There's an example here that shows how to center an arbitrary glyph in an Ellipse2D.Double.
You have to extend the class Shape, which inside you would have to override the paintComponent so that the Graphics2D object knows what to draw.
I'm trying to make a tower of hanoi solver which simply solves the hanoi without any mouse events. The problem is when I move the rectangle the original remains, even after I repaint. I've searched the net and tried changing the code around but nonthing worked. I am using a JFrame with a JPanel inside of it if that changes anything.
I have my disk class here which is just a rectangle with colour.
class Disk extends Rectangle {
Color diskColour;
public Disk(int a, int b, int c, int d, Color colour) {
x = a;
y = b;
width = c;
height = d;
diskColour = colour;
}
public Color getColour() {
return diskColour;
}
public void paintSquare(Graphics g) {
repaint();
g.setColor(diskColour);
g.fillRect(x, y, width, height);
repaint();
}
}
Here is my code where I actually call the paintSquare method:
public void simpleMoveDisk(Disk[] disks, int n, Graphics g) {
disks[n].setLocation(30,25);
disks[n].paintSquare(g);
repaint();
}
The paintSquare method paints the disk, while the setLocation method changes its coordinates.
When this runs the rectangle occurs in the new location, however the old one still remains. Any help is appreciated, thanks in advance.
You are calling repaint() in several places and you shouldn't be.
Have your the top level class that is doing the painting, call the paintSquare method and any other method that is needed. Those methods should not be calling repaint().
Also your simple move disk is really strange in the fact that it passes an array of Disks, an index, and a graphics object. Instead make it just take in a Disk. Just pass it the one out of the array that is needed to be updated. Then let whatever class that calls simpleMoveDisk, separately make a call to repaint instead of trying to paint and update the model in the same method.