Reputation: 57
Solved: Thanks @MadProgrammer
I replaced g2.rotate(Math.toRadians(180.0));
by g2.scale(1, -1);
thanks^^
I wrote program to show Digital Clock with mirror (Vertical Flip)
This is my code
import java.awt.*;
import java.awt.font.GlyphVector;
import javax.swing.*;
import java.util.*;
public class DigitalClock extends JFrame implements Runnable {
/**
* @author HASSAN
*/
Thread runner; // declare global objects
Font clockFont;
Shape mirror;
public DigitalClock() {
super("Digital Clock - Hassan Sharaf 12MCMB33");
setSize(600, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false); // create window
setLocationRelativeTo(null);
clockFont = new Font("digifacewide", Font.BOLD, 100); // create font
Container contentArea = getContentPane();
ClockPanel timeDisplay = new ClockPanel();
contentArea.add(timeDisplay); // add components
setContentPane(contentArea);
start(); // start thread running
}
public class ClockPanel extends JPanel {
public void paintComponent(Graphics painter) {
// super.paintComponent(painter);
Graphics2D g2 = (Graphics2D) painter;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setFont(clockFont); // create clock components
g2.setColor(Color.black);
g2.drawString(timeNow(), 20, 140);
GlyphVector v = clockFont.createGlyphVector(getFontMetrics(clockFont).getFontRenderContext(), timeNow());
mirror = v.getOutline();
g2.translate(553, 160);
g2.rotate(Math.toRadians(180.0));
g2.fill(mirror);
g2.draw(mirror);
}
}
// get current time
public String timeNow() {
Calendar now = Calendar.getInstance();
int hrs = now.get(Calendar.HOUR_OF_DAY);
int min = now.get(Calendar.MINUTE);
int sec = now.get(Calendar.SECOND);
String time = zero(hrs) + ":" + zero(min) + ":" + zero(sec);
return time;
}
public String zero(int num) {
String number = (num < 10) ? ("0" + num) : ("" + num);
return number; // Add leading zero if needed
}
public void start() {
if (runner == null) {
runner = new Thread(this);
}
runner.start();
// method to start thread
}
public void run() {
while (runner == Thread.currentThread()) {
repaint();
// define thread task
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread failed");
}
}
}
// create main method
public static void main(String[] args) {
DigitalClock clock = new DigitalClock();
}
}
Problem: I used rotate() method, but actually I don't want rotate the clock I want flip it vertically Question: How can I flip the shape (not image)?
Upvotes: 2
Views: 2988
Reputation: 347314
You have lots-o-choices depending on what you want to achieve...
You can...
PathIterator
from the shape object, using a AffineTransform
matching your rotational requirements. This will require you to create a new path, appending the PathIterator
to it so you can paint it ... orPath2D
using the shape to be rotated as the base for the new path and passing the AffineTransform
to it. This is pretty much the same as the first option, but requires less code...Here's an example....
public class SpinningTriangle {
public static void main(String[] args) {
new SpinningTriangle();
}
public SpinningTriangle() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new SpinPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SpinPane extends JPanel {
private Triangle triangle;
private float angle = 0;
public SpinPane() {
triangle = new Triangle(50, 100);
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
angle += 2;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(110, 110);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Rectangle bounds = triangle.getBounds();
// PathIterator pi = triangle.getPathIterator(AffineTransform.getRotateInstance(Math.toRadians(angle), bounds.width / 2, bounds.height / 2));
// Path2D path = new Path2D.Float();
// path.append(pi, true);
Path2D path = new Path2D.Float(triangle, AffineTransform.getRotateInstance(Math.toRadians(angle), bounds.width / 2, bounds.height / 2));
int x = (getWidth() - bounds.width) / 2;
int y = (getHeight() - bounds.height) / 2;
g2d.translate(x, y);
g2d.setColor(Color.RED);
g2d.fill(path);
g2d.setColor(Color.YELLOW);
g2d.draw(path);
g2d.dispose();
}
}
public class Triangle extends Path2D.Float {
public Triangle(int width, int height) {
moveTo(width / 2f, 0);
lineTo(width, height);
lineTo(0, height);
closePath();
}
}
}
UPDATED
If all you want to do is "mirror" the shape, you can scale the axis by -1
...
public class SpinningTriangle {
public static void main(String[] args) {
new SpinningTriangle();
}
public SpinningTriangle() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new FlipPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class FlipPane extends JPanel {
private Triangle triangle;
private boolean flip;
public FlipPane() {
triangle = new Triangle(50, 100);
Timer timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
flip = !flip;
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(110, 110);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Rectangle bounds = triangle.getBounds();
double scale = flip ? -1 : 1;
Path2D path = new Path2D.Float(triangle, AffineTransform.getScaleInstance(scale, scale));
int x = (getWidth() - bounds.width) / 2;
int y = (getHeight() - bounds.height) / 2;
if (flip) {
y += bounds.height;
x += bounds.width;
}
g2d.translate(x, y);
g2d.setColor(Color.RED);
g2d.fill(path);
g2d.setColor(Color.YELLOW);
g2d.draw(path);
g2d.dispose();
}
}
public class Triangle extends Path2D.Float {
public Triangle(int width, int height) {
moveTo(width / 2f, 0);
lineTo(width, height);
lineTo(0, height);
closePath();
}
}
}
Upvotes: 3