I am having some trouble while using swing to draw a diamond inside a square.
My code is this,please some one have a look at it and let me know if you can provide a fullfunctional code which is working in creating a diamond inside a square.
The code is:-
import javax.swing.*;
import java.awt.*;
public class MyDrawing extends JPanel
{
static int width=250;
static int height=250;
static int x=0;
static int y=0;
private void doDrawing(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
//for (int i = 0; i <= 1000; i++)
g2d.drawRect(x, y, width,height);
g2d.rotate(Math.toRadians(-45));
System.out.println(Math.toRadians(-45));
x=0;
y=height/2;
System.out.println(y);
width=(int)Math.pow(Math.pow((width/2),2)*2,0.5);
height=width;
System.out.println("width:"+width+"height:"+height);
g2d.drawRect(y, x, width,height);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
To keep the the diamond inside the sqaure, simply
1. Draw a rectangle
2. Rotate the rectangle about its center.
Rectangle2D rectangle = new Rectangle2D.Double(20, 20, 50, 50);
g2.draw(rectangle);
AffineTransform transform = new AffineTransform();
transform.rotate(Math.PI/4, rectangle.getX() + rectangle.width/2, rectangle.getY() + rectangle.height/2);
g2.draw(transform);
Related
I have big problem with coding graphic part of my app, where I need to have components one on top of each other:
First I have JFrame (with fixed size)
In it I have two JPanel components. I want them to have colour background.
That's the easy part.
On one of the JPanel components I want to draw fixed shapres - rectangles, lanes, etc. Here I have problem, that I have two classes: one extends JPanel and is background for this part and second extends JComponent and represents element I draw (there is several elements). I don't know how to draw the elements in the JPanel - I tried several methods and nothing showed up. It's important to me that the JComponents should be drawn and conected only with this JPanel, not with whole frame.
On top of that I want to have moving shapes. It's easy when I have only frame and let's say rectangle, because I only change position and call repaint() method, but how to do this to make the moving shapes be connected to and be inside JPanel and to left previous layers in their place?
For my tries I created few classes with rectangles:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class Main{
public Main() {
JFrame frame = new JFrame();
frame.setSize(1200, 900);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JPanel background = new JPanel();
background.setBackground(Color.lightGray);
GreenRect gr = new GreenRect();
gr.setPreferredSize(new Dimension(500,800));
background.add(gr, BorderLayout.WEST);
RedRect rr = new RedRect();
rr.setPreferredSize(new Dimension(500,800));
background.add(rr, BorderLayout.EAST);
frame.add(background);
}
public static void main(String[] args) {
new Main();
}
}
class GreenRect extends JPanel {
ArrayList<BlackRect> r = new ArrayList<>();
ArrayList<MovingRec> m = new ArrayList<>();
public GreenRect() {
setBackground(Color.green);
addRec(10,10);
addRec(50,50);
addRec(100,100);
addRec(1000,1000);
}
public void addRec(int x, int y) {
r.add(new BlackRect(x,y));
}
}
class RedRect extends JPanel {
public RedRect() {
setBackground(Color.red);
}
}
class BlackRect extends JComponent {
int x, y;
int w = 100, h = 100;
public BlackRect (int x, int y){
this.x = x;
this.y = y;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, w, h);
}
}
class MovingRec extends JComponent {
int x, y;
int w = 20, h = 20;
public MovingRec (int x, int y){
this.x = x;
this.y = y;
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.BLUE);
g2d.fillRect(x, y, w, h);
}
public void update() {
x += 5;
y += 5;
}
}
and now I have problems with points 3 and 4, because I can't place black rectangles on background and moving rectangles on the top.
I will be grateful for all help :)
You do not need to (and shouldn’t) extend BlackRect and MovingRect from JComponent.
For example, BlackRect could be a simple object, like:
class BlackRect {
int x, y;
int w = 100, h = 100;
public BlackRect(int x, int y) {
this.x = x;
this.y = y;
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, w, h);
}
}
You should override GreenRect’s paint method, to paint rectangles on that panel:
public GreenRect extends JPanel {
// Existing members
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (BlackRect black_rect : r) {
black_rect.paint(g2d);
}
// Also paint list of moving rectangles here
}
}
When GreenRect.repaint() is called, it will paint its background, and all rectangles from the r (and m list when you add that code). If the m rectangles have had their positions updated, they will be drawn at their new positions, so they will appear to be moving. Since moving rectangles are drawn last, they would appear “on top”.
Use a Swing Timer to drive the animation. When the timer expires, it should move all of the moving rectangles slightly (ie, call MovingRec.update()), and call repaint() on GreenRect.
Hello I wonder if anyone can help me , I have declared 2 values x1, y1 both as 120 and trying to use these in the following method:
private void drawDot(int x, int y, Graphics2D twoD) {
twoD.fillOval(x-50, y-50, 100, 100);
}
However when I use drawDot(120,120,twoD) it paints the filled oval in the wrong place compared to when I manually use
twoD.fillOval(70,70,100,100);
Shouldn't these 2 statements do the exact same thing? Is there something I am missing? I have added an image to show the issue, the oval on the left is the oval drawn by my drawDot method and the oval on the right is the oval in the correct place as it should be. If anyone has any advice it would be greatly appreciated. Thanks
click this link to see how both ovals are drawn
the entire class:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DieFace extends JPanel {
int x1,y1 = 120;
int x2,y2 = 300;
int x3,y3 = 480;
private BufferedImage bufferedImage;
public DieFace() {
this.init();
this.frameInit();
updateVal(1);
}
private void init() {
this.setPreferredSize(new Dimension(600,600));
}
private void frameInit() {
JFrame window = new JFrame("Dice Simulation");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setContentPane(this);
window.pack();
window.setVisible(true);
window.setLocationRelativeTo(null);
}
public void paintComponent(Graphics g) {
Graphics2D twoD = (Graphics2D) g;
twoD.drawImage(bufferedImage,0,0,null);
}
private void drawDot(int x, int y, Graphics2D twoD) {
twoD.fillOval(x-50, y-50, 100, 100);
}
public void updateVal(int dieRoll) {
bufferedImage = new BufferedImage(600,600,BufferedImage.TYPE_INT_ARGB);
Graphics2D twoD = bufferedImage.createGraphics();
twoD.setColor(Color.WHITE);
twoD.fillRect(0, 0, 600, 600);
twoD.setColor(Color.BLACK);
if(dieRoll==1) {
drawDot(x1,y1,twoD);
twoD.fillOval(70, 70, 100, 100);
}
repaint();
}
}
Shouldn't these 2 statements do the exact same thing? Is there something I am missing?
Because you made a mistake in your variable initializations on x1, y1:
int x1,y1 = 120; //This means x1 = 0, y1 = 120
What you actually wanted is:
int x1 = 120, y1 = 120;
Since x1 is not 120, when you invoke
drawDot(x1,y1,twoD);
drawDot(0, 120, twoD); is being invoked
Hence both elipses will appear on the same y-axis, but different on the x-axis.
Here's the class in which I try to draw the lines
package gps;
import java.awt.*;
import java.awt.geom.Line2D;
import java.util.*;
import javax.swing.*;
public class RoadMap extends JPanel {
public void paintComponent(Graphics2D g)
{
super.paintComponent(g);
g.setColor(Color.blue);
for(int i = 0; i < Graph.getEdges().length; i++)
{
Shape s = new Line2D.Double(Graph.vMap.get(Graph.getEdges()[i].i1).x,
Graph.vMap.get(Graph.getEdges()[i].i1).y,
Graph.vMap.get(Graph.getEdges()[i].i2).x,
Graph.vMap.get(Graph.getEdges()[i].i2).y);
g.draw(s);
}
}
}
The Graph.vMap.get(Graph.getEdges()[i].i2).x and Graph.vMap.get(Graph.getEdges()[i].i2).y access the x and y values for the endpoints of the lines and I've tested it and it returned the correct values. However, nothing shows up in my JFrame with this. Trying to draw other lines with set values outside of the for loop actually worked.
x1 = 43.12929, x2 = 43.12976, y1 = -77.626956, y2 = -77.62679
These y values are outside the panel. AWT/Swing component visible coordinate space runs from (0, 0) to (width-1, height-1).
Check where you are computing the values. If you want (0, 0) to be the center, you need to do some arithmetic or a translation via e.g. Graphics2D#translate(int, int).
Furthermore:
public void paintComponent(Graphics2D g)
If you are trying to override paintComponent, you have not done so. paintComponent takes a Graphics, not a Graphics2D:
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Always use the #Override annotation when you attempt to override, because it will cause an error and tell you if it's not an override. See https://docs.oracle.com/javase/tutorial/java/IandI/override.html.
Possibly you mean to use something like this:
public class RoadMap extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.translate(getWidth() / 2, getHeight() / 2);
g2.setColor(Color.blue);
for(int i = 0; i < Graph.getEdges().length; i++) {
Shape s = new Line2D.Double(
Graph.vMap.get(Graph.getEdges()[i].i1).x,
Graph.vMap.get(Graph.getEdges()[i].i1).y,
Graph.vMap.get(Graph.getEdges()[i].i2).x,
Graph.vMap.get(Graph.getEdges()[i].i2).y);
g2.draw(s);
}
g2.dispose();
}
}
I was reading Core Java and encountered this code snippet:
package draw;
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class DrawTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new DrawFrame();
frame.setTitle("DrawTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class DrawFrame extends JFrame
{
public DrawFrame()
{
add(new DrawComponent());
pack();
}
}
class DrawComponent extends JComponent
{
private static final int DEFAULT_WIDTH = 400;
private static final int DEFAULT_HEIGHT = 400;
public void paintCompent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
// draw a rectangle
double leftX = 100;
double topY = 100;
double width = 200;
double height = 150;
Rectangle2D rect = new Rectangle2D.Double(leftX, topY, width, height);
g2.draw(rect);
// draw the enclosed ellipse
Ellipse2D ellipse = new Ellipse2D.Double();
ellipse.setFrame(rect);
g2.draw(ellipse);
// draw a diagonal line
g2.draw(new Line2D.Double(leftX, topY, leftX + width, topY + height));
// draw a circle with the same center
double centerX = rect.getCenterX();
double centerY = rect.getCenterY();
double radius = 150;
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX + radius, centerY + radius);
g2.draw(circle);
}
public Dimension getPreferredSize()
{
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
I tried this code on Eclipse, it did run but, instead of rectangles, ellipse, diagonal lines and circle, there appeared nothing in the frame. I double-checked the code against the book, there was no typo. What is wrong?
There's a spelling mistake...
public void paintCompent(Graphics g) {
should be
public void paintComponent(Graphics g) {
This is why you should use the #Override annotation, as it will give you a compile time error when you try to override a method that doesn't exist within the parent hierarcy.
You should also be calling super.paintComponent(g); before performing any custom painting
Like in a topic, I've readed the most of all solutions for repaint() but for my code their are not working. I'm a begginer so forgive me a mess in my code..
class View.java
public class View extends JFrame{
public void make(){
setSize(640,480);
setVisible(true);
setTitle("Parking");
}
double x_ = MyFrame.x;
double y_ = MyFrame.y;
double odchylenie_ = MyFrame.odchylenie;
int szerokosc = 50;
int wysokosc = 30;
public void paint(Graphics g){
Rectangle2D rect = new Rectangle2D.Double(-szerokosc / 2., -wysokosc / 2., szerokosc, wysokosc);
AffineTransform transform = new AffineTransform();
transform.translate(x_, y_);
transform.rotate(Math.toRadians(odchylenie_));
Shape rotatedRect = transform.createTransformedShape(rect);
Graphics2D g2 = (Graphics2D)g;
g2.draw(rotatedRect);
}
All I want to do to re-paint this rotatedRect with new values of x,y and odchylenie (sorry for polish variable names).
I'm calculating new variable values and using Jbutton to redraw it.
Here is my MyFrame.class
public class MyFrame extends javax.swing.JFrame {
static double x,y,odchylenie,kat;
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
View v = new View();
v.make();
Fuzzy f = new Fuzzy();
kat = f.wyjscie(x, odchylenie);
jLabel5.setText("Kąt: " + Double.toString(kat));
odchylenie = Fuzzy.wyliczOdchylenie(odchylenie,kat);
jLabel8.setText("Nowe odchylenie: " + Double.toString(odchylenie));
x = Fuzzy.wyliczX(x, 10, kat,odchylenie);
jLabel6.setText("Nowy x: " + Double.toString(x));
y = Fuzzy.wyliczY(y,x, 10, kat,odchylenie);
jLabel7.setText("Nowy y: " + Double.toString(y));
v.repaint(); //Not works
}
Instead of doing repaint(), the new window appears, and old one stays...
I have tried to declare View v outside the button function body, but it not worked too(nothing is painting).
Whenever you override one of the paint() methods, you need to make a call to the super's method:
public void paint(Graphics g) {
super.paint(g);
// your code goes here
}
Further, you should really be using paintComponent(), not paint().
public void paintComponent(Graphics g) {
super.paintComponent(g);
// your code goes here
}
Instead of using paint, use paintComponent:
public void paintComponent(Graphics g){
super.paintComponent(g);
Rectangle2D rect = new Rectangle2D.Double(-szerokosc / 2., -wysokosc / 2., szerokosc, wysokosc);
AffineTransform transform = new AffineTransform();
transform.translate(x_, y_);
transform.rotate(Math.toRadians(odchylenie_));
Shape rotatedRect = transform.createTransformedShape(rect);
Graphics2D g2 = (Graphics2D)g;
g2.draw(rotatedRect);
}