使用Swing和Graphics2D在Java中旋转滚轮?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Swing和Graphics2D在Java中旋转滚轮?相关的知识,希望对你有一定的参考价值。
我正在研究一个可以围绕中心旋转轮子的课程。轮子是使用graphics2d创建的,但我无法弄清楚如何让轮子围绕中心旋转。目前,车轮旋转,但不完全是关于原点。
我的最终目标是制造轮子,使其成为多色的,以及围绕它的程序,但我的主要关注点是让旋转轮工作。如果你能指出我正确的方向,我将永远感激不尽!
这是我目前的代码:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;
public class RotateApp {
private static final int N = 3;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout(N, N, N, N));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new RotatePanel());
frame.pack();
frame.setVisible(true);
System.out.println();
}
});
}
}
class RotatePanel extends JPanel implements ActionListener {
private static final int SIZE = 256;
private static double DELTA_THETA = Math.PI / 90;
private final Timer timer = new Timer(25, this);
private Image image = RotatableImage.getImage(SIZE);
private double dt = DELTA_THETA;
private double theta;
public RotatePanel() {
this.setBackground(Color.lightGray);
this.setPreferredSize(new Dimension(
image.getWidth(null), image.getHeight(null)));
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
image = RotatableImage.getImage(SIZE);
dt = -dt;
}
});
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.translate(this.getWidth() / 2, this.getHeight() / 2);
g2d.rotate(theta);
g2d.translate(-image.getWidth(this) / 2, -image.getHeight(this) / 2);
g2d.drawImage(image, 0, 0, null);
}
public void actionPerformed(ActionEvent e) {
theta += dt;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
}
class RotatableImage {
private static final Random r = new Random();
static public Image getImage(int size) {
BufferedImage bi = new BufferedImage(
size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.getHSBColor(r.nextFloat(), 1, 1));
g2d.setStroke(new BasicStroke(10.0f));
g2d.draw(new Line2D.Double(0, 100, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 200, 100));
g2d.draw(new Line2D.Double(100, 0, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 100, 200));
g2d.draw(new Line2D.Double(25, 25, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 175, 175));
g2d.draw(new Line2D.Double(175, 25, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 25, 175));
g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));
g2d.dispose();
return bi;
}
}
答案
您可以使用Rotated Icon类为您进行旋转,这样您就不必担心所有旋转逻辑,并且旋转逻辑位于可重用的类中。
使用此类的一个示例是:
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class Rotation4 extends JPanel
{
private JLabel label;
private Icon icon;
private Icon rotated;
private int degrees;
public Rotation4(Image image)
{
icon = new ImageIcon( image );
label = new JLabel(icon);
label.setPreferredSize( label.getPreferredSize() );
add( label );
setDegrees( 0 );
}
public void setDegrees(int degrees)
{
this.degrees = degrees;
double radians = Math.toRadians( degrees );
rotated = new RotatedIcon(icon, degrees);
label.setIcon(rotated);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
Image bi = RotatableImage.getImage(210);
final Rotation4 r = new Rotation4(bi);
final JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
slider.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent e)
{
int value = slider.getValue();
r.setDegrees( value );
}
});
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JScrollPane(r));
f.add(slider, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
static class RotatableImage
{
private static final Random r = new Random();
static public Image getImage(int size)
{
BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bi.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.getHSBColor(r.nextFloat(), 1, 1));
g2d.setStroke(new BasicStroke(10.0f));
g2d.draw(new Line2D.Double(5, 105, 205, 105));
/*
g2d.draw(new Line2D.Double(100, 100, 200, 100));
g2d.draw(new Line2D.Double(100, 0, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 100, 200));
g2d.draw(new Line2D.Double(25, 25, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 175, 175));
g2d.draw(new Line2D.Double(175, 25, 100, 100));
g2d.draw(new Line2D.Double(100, 100, 25, 175));
*/
g2d.draw(new Ellipse2D.Double(5, 5, 199, 199));
g2d.setColor(Color.BLACK);
g2d.fillOval(100, 100, 10, 10);
g2d.dispose();
return bi;
}
}
}
注意我还必须对您的图像和绘画进行更改。无论您是使用RotatedIcon还是自己执行旋转代码,都需要进行以下更改:
- 图像大小更改为210.这是因为您的笔触大小为10,因此您需要考虑圆形轮廓中的额外像素。
- 您需要将圆的原始值改为笔划大小的一半。所以在这种情况下,原点变为(5,5)。
- 椭圆的大小需要改为199.这是因为椭圆的轮廓被绘制的方式。轮廓需要1个额外的像素。如果将尺寸保留为200,则轮廓的1个像素将丢失。当使用10的笔触大小时,这不是很明显,但如果使用1的大小,则右边和底边的轮廓将丢失。
- 您的线路位置需要更改。你不希望线条直接到圆的边缘,因为那样你将在边缘处得到一条扁平线而不是圆形线。所以我开始从开始的5个像素的行,并结束它从结束5像素。
另一答案
好的,只需要很少的修改和更少的“辐条”,我的轮子旋转为中心(1.)和多色(2.):
更新1.)要在您的(原始)代码中进行中心旋转,只需更改qazxsw posito 200!
SIZE
说明:
- 所以你的解决方案中的“摆动”来自于这样一个事实:你将图像和容器/面板尺寸设置为256x256,但仅仅基于200x200的车轮布局。我修正了所有的尺寸,画了一个正确的十字架,然后
import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridLayout; import java.awt.Image; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.swing.*; public class RotateApp { private static final int N = 3; public static void main(String[] args) { EventQueue.invokeLater(() -> { JFrame frame = new JFrame(); frame.setLayout(new GridLayout(N, N, N, N)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new RotatePanel()); frame.pack(); frame.setVisible(true); System.out.println(); }); } } class RotatePanel extends JPanel implements ActionListener { private static final int SIZE = 256; private static final double DELTA_THETA = Math.PI / 90; private final Timer timer = new Timer(25, this); private Image image = RotatableImage.getImage(SIZE); private double dt = DELTA_THETA; private double theta; public RotatePanel() { this.setBackground(Color.lightGray); this.setPreferredSize(new Dimension(SIZE, SIZE)); this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { dt = -dt; image = RotatableImage.getImage(SIZE); } }); timer.start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; g2d.rotate(theta,128,128); g2d.drawImage(image, 0, 0, null); } @Override public void actionPerformed(ActionEvent e) { theta += dt; repaint(); } @Override public Dimension getPreferredSize() { return new Dimension(SIZE, SIZE); } } class RotatableImage { private static final Random r = new Random(); static public Image getImage(int size) { BufferedImage bi = new BufferedImage( size, size, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = bi.createGraphics(); g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); final Color c1 = Color.getHSBColor(r.nextFloat(), 1, 1); final Color c2 = Color.getHSBColor(r.nextFloat(), 1, 1); g2d.setPaint(c1); g2d.setStroke(new BasicStroke(10.0f)); g2d.draw(new Line2D.Double(0, size/2, size, size/2)); g2d.setPaint(c2); g2d.draw(new Line2D.Double(size/2, 0, size/2, size)); g2d.setPaint(c1); g2d.draw(new Ellipse2D.Double(0, 0, size, size)); g2d.dispose(); return bi; } }
(!)与中心相关联。 - 多色(简单):你可以在每个形状之间调用
g2d.rotate(theta,128,128);
! ;)
以上是关于使用Swing和Graphics2D在Java中旋转滚轮?的主要内容,如果未能解决你的问题,请参考以下文章