Double colored oval - java

I am a bit new in java and i have this stuff for homework. I have to make something like this
The thing is that i have no idea how to make the circle double colored with yellow and black stuff. Also after that with use of Threads i have to make it rotate counter clock wise. Here is my code for the circle, i know how to create it, just don't know how to multi color it >.< .
import java.awt.*;
import java.awt.event.*;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.JComboBox;
import javax.swing.JApplet;
import javax.swing.JSlider;
import java.awt.Color;
import java.awt.Graphics;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JApplet;
public class Lab4a extends JApplet implements Runnable {
public void init() {
Thread t = new Thread(this);
t.start();
}
public void paint(Graphics g){
super.paint(g);
int w = getWidth();
int h = getHeight();
g.drawOval(25, 35, 200, 200);
g.drawOval(45, 55, 160, 160);
}
}

Have a look at drawArc instead of drawOval. With this, you can paint arcs -- parts of ovals. You can specify the start and end angle of the arc, which can then also be used for drawing it in different states when it needs to rotate.

Related

Sanity check: why is there a gap between vertical lines drawn using Graphics.drawLine at x and x+1?

I was surprised when I found there exists a gap between two vertical lines drawn at x and x+1 using myGraphics.drawLine(x,someY,x,someOtherY). My canvas is a JPanel with an overridden paintComponent(Graphics).
Why is this and how to prevent it?
Here's a screenshot of the gap:
Code
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.time.LocalTime;
public class rough {
public static void main(String[] args) {
var pn=new JPanel(){
#Override
protected void paintComponent(Graphics gg) {
super.paintComponent(gg);
var g=(Graphics2D)gg;
var x=10;
var h=getHeight();
g.drawLine(x,0,x,h);
x+=1;
g.setColor(Color.red);
g.drawLine(x,0,x,h);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200,200);
}
};
var fr=new JFrame(LocalTime.now().toString());
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
fr.getContentPane().add(pn);
fr.pack();
fr.setVisible(true);
}
}
Env:
OpenJDK 16
Windows 20H2
Display scaling: 150% (motivated by #Pshemo's comment)
Screen resolution: 1920 by 1080

Java3D: I can't see my triangle

I'm very new to Java3D and try to show a triangle, but it does not show up, the frame is completely black.
If i add
bg.addChild(new ColorCube(0.3));
it shows a red square in the middle (so generally showing shapes should work, shouldn't it?)
I don't really know if the problem is with the construction of the triangle itself or with some other part of the View, e.g. the triangle is not in focus, too small, not lit, etc. Do polygons from TriangleArray have to be lit by a source, or do they appear as matt objects?
Here is the code:
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.geometry.GeometryInfo;
import com.sun.j3d.utils.geometry.NormalGenerator;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import javax.swing.JFrame;
import javax.media.j3d.*;
import javax.vecmath.Color3f;
import javax.vecmath.Color4f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
public class Simulator extends Frame {
Point3f[] testTrianglePoints = {
new Point3f(0.0f ,0.0f, 1.0f),
new Point3f(0.0f, 0.0f, 1.2f),
new Point3f(0.2f, 0.2f, 1.2f)};
Simulator() {
System.out.println("Simulator window initiated");
}
public void run() {
SimpleUniverse u = new SimpleUniverse();
BranchGroup bg = new BranchGroup();
//bg.addChild(new ColorCube(0.3));
TriangleArray t_geo = new TriangleArray(9, TriangleArray.COORDINATES);
t_geo.setCoordinates(0,testTrianglePoints);
GeometryArray t_geoArray = (new GeometryInfo(t_geo)).getGeometryArray();
Shape3D t_shape = new Shape3D(t_geoArray,new Appearance());
bg.addChild(t_shape);
u.addBranchGraph(bg);
u.getViewingPlatform().setNominalViewingTransform();
}
}
`

Java Swing drawing PlayButton for a basic music player

Maybe my case it's a simple confusion of ideas. How do draw a button like this using Shape?
I don't mind the rounded corners, heres my aproach for a round corner button.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.basic.BasicButtonUI;
public class PlayButtonUI extends BasicButtonUI{
protected Shape shape;
#Override
protected void installDefaults(AbstractButton b) {
super.installDefaults(b);
b.setOpaque(false);//removes that annoying default background
}
#Override public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D)g;
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
drawButtonShape(b);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
if(model.isArmed()) {
g2.setColor(Color.RED);//color when button is pressed
}else{
g2.setColor(Color.GREEN);//default button color
}
g2.fill(shape);//aplying color
super.paint(g2, c);
}
private void drawButtonShape(JComponent c) {
//button shape is drawn here, 16 are the border radius
shape = new RoundRectangle2D.Float(0, 0, c.getWidth()-1, c.getHeight()-1,16, 16);
}
}
I don't really know how to draw anything at all, this class was a result from a chaotic example that i found somewhere, and then simplified by myself until it just worked, i left some comments for the important lines.
I've been looking for a while, and found this example in oracle docs.
https://docs.oracle.com/javase/tutorial/2d/geometry/arbitrary.html
I don't really know how to convert Graphics2D to Shape, please tell me if i'm taking the wrong way.
So, I've spent the better of the day banging my head against this problem, trying to do a whole bunch of trig magic ... I can't even do simple card tricks :P
Then I realised, there are other tricks I could do...
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
JButton btn = new JButton();
btn.setUI(new PlayButtonUI());
frame.add(btn);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PlayButtonUI extends BasicButtonUI {
#Override
public Dimension getPreferredSize(JComponent c) {
return new Dimension(200, 200);
}
#Override
public void paint(Graphics g, JComponent c) {
Graphics2D g2 = (Graphics2D) g;
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//smoth borders
if (model.isArmed()) {
g2.setColor(Color.BLACK);//color when button is pressed
} else {
g2.setColor(Color.GRAY);//default button color
}
float thinkness = Math.min(c.getWidth(), c.getHeight()) * 0.1f;
Shape shape = shapeFor(c, thinkness);
g2.setStroke(new BasicStroke(thinkness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.fill(shape);//aplying color
g2.draw(shape);
super.paint(g2, c);
}
private Shape shapeFor(JComponent c, float thickness) {
GeneralPath gp = new GeneralPath();
double width = c.getWidth();
double height = c.getHeight();
double vPos = height / 2.0;
double hPos = width - thickness;
gp.moveTo(0.0 + thickness, 0.0 + thickness);
gp.lineTo(hPos, vPos);
gp.lineTo(0.0 + thickness, height - thickness);
gp.closePath();
return gp;
}
}
}
So, this is a slight "cheat". What this actually does is uses the properties of the Stroke to generate rounded edges, rather than trying to use curveTo or compound shapes
Have a look at Stroking and Filling Graphics Primitives for more details

Java Swing + Timer? Moving a line across JPanel

What I'm trying to do is simple. I have a JLayeredPane with two panels inside of it. Panel 2 (higher Z index) has a transparent background and only displays a Line2D element that goes from Y = 0 to Y = max. I need the X value to increment every so many milliseconds, and then redraw the line. I have everything set up to do so, except I can't figure out how to do the bar movement via timing.
I've done some research and every time I saw mentions of the timer class (Which I feel would be able to accomplish what I'm trying to do) people recommend not using it. I can't figure out an alternative to using the timer class in order to slide my bar across the screen.
Hope this code helps you. It does exactly what you want.
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.Arrays;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class FloorPlaner extends JFrame {
public int x=0;
public FloorPlaner(){
super("FloorPlaner");
requestFocus();
setContentPane(new DrawingPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
setResizable(true);
setVisible(true);
while (true) {
x++;
repaint();
try {
Thread.sleep(40); //25 FPS
} catch(InterruptedException bug) {
Thread.currentThread().interrupt();
System.out.println(bug);
}
}
}
class DrawingPane extends JPanel { //Where you actually draw on
public void paintComponent(Graphics g) { //Drawing method
g.drawLine(x,0,x,400);
}
}
public static void main(String args[]) {
new FloorPlaner(); //Start it
}
}

Paint from different classes

I'm trying to make a game in Java (school project) and I have the following setup:
A main class, extended with JFrame, a 'Game' class, extended with JPanel.
Now from within this main class, I make calls to a class 'Player' and a class 'Map'.. The class 'Map' exists of two subclasses 'Blocks' and 'Bombs'.
But I'm wondering.. How do I let the paint methods of all this classes paint to the same JPanel (of the class Game)?
I gave every class the method 'public void paint(Graphics g)' and do the painting.. But only the painting of the class 'Game' shows up when i run the program, not the painting from the subclasses.
How do I implement this?
By example, I reduced my code to this:
Main class:
BomberGame game = new BomberGame();
add(game);
setSize(400, 400);
setTitle("Bomber");
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.show();
}
public static void main(String[] args) {
BomberB1 main = new BomberB1();
}
}
Game class:
package bomberb1;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class BomberGame extends JPanel {
public BomberGame() {;
BomberMap map = new BomberMap(this);
}
public void paint(Graphics g) {
g.drawRect(10, 10, 10, 10);
g.setColor(Color.red);
g.fillRect(10, 10, 10, 10);
}
}
Map class:
package bomberb1;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.*;
import javax.swing.SwingUtilities;
public class BomberMap{
BomberGame game;
public BomberMap(BomberGame game) {
this.game = game;
}
public void paint(Graphics g) {
g.drawRect(30, 30, 20, 20);
}
}
In the Entity class (which could be Map player etc) to be drawn have a draw method that accepts a Graphics object thus allowing it to access the Graphics object of the JPanel and draw to it, something like:
class GamePanel extends JPanel {
Entity e=new Entity;
#Override
protected paintComponent(Graphics g) {
super.paintComponent(g);
e.draw(g);//call draw method for entity and pass graphics object
}
}
class Entity {
//will draw whats necessary to Graphics object
public void draw(Graphics g) {
//draw to the graphics object here
}
}
Other suggestions:
Do not extend JFrame class unnecessarily
override JPanel paintComponent() and not paint() (+1 to trashGod comment)
Swing components should be created and manipulated on Event Dispatch Thread via SwingUtilities.invokeLater(..) block.
UPDATE:
As #GuillaumePolet stated a better game design would be implementing JPanels as parent class for most of the game entities see this similar answer for more.

Categories