Java 调整JFrame大小后,如何计算圆形状的X-Y坐标和半径?
我正在使用JComponent(AWT/SWING)在JFrame上绘制圆,我想确保当用户调整帧的大小时,会进行某些计算并在屏幕上动态绘制圆(无论它是大、小、向左还是向右移动等)。我实现了Java 调整JFrame大小后,如何计算圆形状的X-Y坐标和半径?,java,swing,awt,Java,Swing,Awt,我正在使用JComponent(AWT/SWING)在JFrame上绘制圆,我想确保当用户调整帧的大小时,会进行某些计算并在屏幕上动态绘制圆(无论它是大、小、向左还是向右移动等)。我实现了ComponentAdapter事件和componentresistized方法,但是我很难想出一些动态的方法。这是我的密码: 循环器类 import javax.swing.JFrame; import java.awt.event.*; public class CircleViewer { pu
ComponentAdapter
事件和componentresistized
方法,但是我很难想出一些动态的方法。这是我的密码:
循环器类
import javax.swing.JFrame;
import java.awt.event.*;
public class CircleViewer
{
public static void main(String[] args)
{
final JFrame frame = new JFrame("Circle Shapes");
final CirclePanel panel = new CirclePanel();
// Class for Mouse Listener which implements the necessary interfaces
class MousePressListener implements MouseListener, MouseMotionListener
{
public void mouseClicked(MouseEvent event) { }
public void mouseEntered(MouseEvent event) { }
public void mouseExited(MouseEvent event) { }
public void mouseWheelMoved(MouseWheelEvent event) { }
public void mouseMoved(MouseEvent event) { }
public void mousePressed(MouseEvent event) { }
@Override
public void mouseDragged(MouseEvent event)
{
var x = event.getX();
var y = event.getY();
panel.moveTo(x, y);
}
@Override
public void mouseReleased(MouseEvent event)
{
panel.finalMove();
}
}
panel.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent event)
{
panel.frameResizeCalculation(frame.getWidth(), frame.getHeight());
}
});
MousePressListener listener = new MousePressListener();
panel.addMouseListener(listener);
panel.addMouseMotionListener(listener);
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
}
public static final int FRAME_WIDTH = 700;
public static final int FRAME_HEIGHT = 500;
}
环板类
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import java.util.ArrayList;
import java.awt.Color;
import java.lang.Math;
import java.awt.BasicStroke;
import java.awt.Stroke;
public class CirclePanel extends JComponent
{
private int mouseX;
private int mouseY;
private ArrayList<Circle> circleList;
private final BasicStroke dashLine = new BasicStroke(1,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL,
0, new float[]{6}, 0);
private Circle newCircle;
private final Color newCircleColor = Color.RED;
private final Color finalCircleColor = Color.BLUE;
public CirclePanel()
{
this.circleList = new ArrayList<Circle>();
this.mouseX = 0;
this.mouseY = 0;
}
public void moveTo(int x, int y)
{
mouseX = x;
mouseY = y;
if (newCircle == null)
{
newCircle = new Circle(x,y,0);
}
else
{
int dX = newCircle.get(0) - mouseX;
int dY = newCircle.get(1) - mouseY;
newCircle.set(2, (int)Math.sqrt(dX*dX + dY*dY));
}
repaint();
}
public void finalMove()
{
if (newCircle != null)
{
circleList.add(newCircle);
newCircle = null;
repaint();
}
}
// Do something here and change X-Y coordinates and radius of the circles and finally call repaint() method of Graphics2D
public void frameResizeCalculation(int width, int height)
{
var dX = CircleViewer.FRAME_WIDTH - width;
var dY = CircleViewer.FRAME_HEIGHT - height;
}
public void paintComponent(Graphics g)
{
g.setColor(finalCircleColor);
for (Circle circle : circleList)
{
drawCircle(g, circle);
}
Circle c = newCircle;
if (c != null)
{
g.setColor(newCircleColor);
drawCircle(g, c);
Graphics2D g2 = (Graphics2D)g.create();
g2.setStroke(dashLine);
g2.drawLine(c.get(0), c.get(1), mouseX, mouseY);
g2.dispose();
}
}
public void drawCircle(Graphics g, Circle c)
{
g.drawOval(c.get(0) - c.get(2), c.get(1) - c.get(2), c.get(2) * 2, c.get(2) * 2);
}
}
进行某些计算并在屏幕上动态绘制圆圈(无论大小、向左或向右移动等)
好的,你需要定义你想发生什么,当帧被调整大小。我们不能告诉你该怎么做
但是,在您担心这些之前,您需要重新构造类,以使动态绘制成为可能
我发现基本代码存在以下问题:
getPreferredSize()
方法以返回组件的首选大小。然后在代码中将面板添加到框架中,然后在框架上调用pack()
方法draw(Graphics-Graphics)
。然后使用类的属性绘制椭圆。这意味着paintComponent()方法将调用Circle类的draw(…)方法,您将删除当前拥有的drawOval(…)方法paintComponent(…)
方法添加逻辑。每次面板大小更改时,都会自动调用paintComponent()方法。基本逻辑是确定绘制每个圆时要使用的“乘数”
因此,您可以使用getPreferredSize()
方法获得首选宽度,也可以使用面板的getWidth()
方法获得当前大小。所以你的乘数是:
double multiplierX = getWidth() / getPreferredSize().x;
现在需要将此信息传递给Circle objects draw(…)方法,因此方法签名将变成draw(Graphics g,double multiplierX)
。调用drawOval(…)
方法时,将乘数应用于“x”参数。这将导致圆在调整帧大小时沿水平方向移动
然后重复上述步骤,使倍增器的圆沿垂直方向移动
然后需要决定如何影响半径
double multiplierX = getWidth() / getPreferredSize().x;