Java PopUp类似乎加快了动画的速度
我有一个名为PopUp的类,它是一个JPanel,当激活时,它会根据中心给定的参数扩展到给定的大小和位置,并在单击时以相同的方式收缩 由于某些原因,当弹出窗口扩展和收缩时,共享相同JPanel的动画会加速。我已经在两个程序中看到了这一点,我在这两个程序中使用了我的弹出类 以下是我认为相关规范的内容:Java PopUp类似乎加快了动画的速度,java,swing,timer,jpanel,graphics2d,Java,Swing,Timer,Jpanel,Graphics2d,我有一个名为PopUp的类,它是一个JPanel,当激活时,它会根据中心给定的参数扩展到给定的大小和位置,并在单击时以相同的方式收缩 由于某些原因,当弹出窗口扩展和收缩时,共享相同JPanel的动画会加速。我已经在两个程序中看到了这一点,我在这两个程序中使用了我的弹出类 以下是我认为相关规范的内容: /** * The {@code PopUp} class is a JPanel that expands to the rectangle * created from the given
/**
* The {@code PopUp} class is a JPanel that expands to the rectangle
* created from the given x, y, width and height that expands from
* the center of the rectangle.
* <p>
* Here is an example of how the {@code PopUp} object can be initialized:
* <blockquote><pre>
* PopUp pu = new PopUp(25, 25, 575, 575, 25, Color.GRAY);
* </pre></blockquote>
* <p>
* The class {@code PopUp} includes methods for drawing the pop-up;
* choosing whether the pop-up is expanding or not; getting the
* percentage that the pop-up is expanded; and getting the maximum x, y,
* width, and height
*
* @author Gigi Bayte 2
*/
public class PopUp extends JPanel implements MouseListener {
private static final long serialVersionUID = 1L;
/**
* Expanded x coordinate
*/
private double x;
/**
* Expanded y coordinate
*/
private double y;
/**
* Expanded width value
*/
private double width;
/**
* Expanded height value
*/
private double height;
/**
* Number of steps until fully expanded
*/
private int steps;
/**
* This divided by steps is the percentage the pop-up is expanded
*/
private int expansionStage = 0;
/**
* Whether or not the pop-up is expansing
*/
private boolean isExpanding = false;
/**
* Color of the pop-up
*/
private Color color;
/**
* The rectangle that represents the bounds of the pop-up
*/
private Rectangle2D popUp;
/**
* Initializes a newly created {@code PopUp} with a uniform color
* @param x The x coordinate of the expanded pop-up
* @param y The y coordinate of the expanded pop-up
* @param w The width of the expanded pop-up
* @param h The height of the expanded pop-up
* @param expansionSteps The number of steps until fully expanded
* @param popUpColor The color of the pop-up
*/
public PopUp(double x, double y, double w, double h, int expansionSteps, Color popUpColor) {
this.x = x;
this.y = y;
width = w;
height = h;
color = popUpColor;
steps = expansionSteps;
popUp = new Rectangle2D.Double(0, 0, width, height);
addMouseListener(this);
}
/**
* Draws the pop-up
* @param g Graphics object from paintComponent
*/
public final void draw(Graphics g) {
if(isExpanding)
expansionStage = Math.min(expansionStage + 1, steps);
else
expansionStage = Math.max(expansionStage - 1, 0);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform trans = new AffineTransform();
trans.translate(x + width/2 * (1 - (double) expansionStage/steps), y + height/2 * (1 - (double) expansionStage/steps));
trans.scale((double) expansionStage/steps, (double) expansionStage/steps);
setBounds((int) trans.getTranslateX(), (int) trans.getTranslateY(), (int) (width * expansionStage/steps), (int) (height * expansionStage/steps));
g2d.setColor(color);
Shape transformed = trans.createTransformedShape(popUp);
g2d.fill(transformed);
}
/**
* Sets whether the pop-up is expanding or not
* @param expanding Whether or not the pop-up should expand
*/
public final void setExpanding(boolean expanding) {
isExpanding = expanding;
}
@Override
public final void mouseClicked(MouseEvent e) {
isExpanding = false;
}
}
从上面的示例中可以看出,每次弹出窗口扩展或收缩时,文本从右向左滚动的速度都会加快。我发现了问题所在。罪魁祸首就在这里: 显然,快速连续地将JPanel扩展到不同的尺寸会导致一些速度扭曲,原因我不知道。我希望能对这个答案进行编辑,对这个现象做出更好的解释
我只是为JPanel设置了一个静态大小,并让图形完成其余的工作。这是在接收调用
paintComponent()
的重复更新事件时的预期行为;调整此大小以再现效果
为什么重复的更新事件会导致这种情况?背后的逻辑是什么
在draw()
方法中对的每次调用都“使组件层次结构无效”。API确保
当层次结构失效时,例如在更改组件的边界之后,或者在容器中添加/删除组件之后,必须通过在层次结构最顶部的无效容器上调用的Container.validate()
方法来验证整个层次结构
由于该方法“可能是一个相当耗时的操作”,因此您可以“将层次结构的验证推迟到一组布局相关操作完成”,如您所示;或者,您可以使用如图所示的。调整动画的速度,这是在接收调用
paintComponent()
的重复更新事件时的预期行为;调整大小以再现效果;有关更多详细信息,请在您的问题中包含一个显示您所描述问题的答案。完成@对不起,没时间补上丢失的东西。什么时候调用您的ActionListener
?另请参见。每当计时器滴答作响时,就会调用它。我会调查你发送的链接@trashgod@trashgod也许你可以帮我填写我的答案中缺少的部分?如前所述,“重复的更新事件…调用paintComponent()
”问题是反复调整JPanel的大小。删除上面的行后,我仍然有一个计时器反复调用paintComponent(),它工作正常@垃圾神调整上述AnimationTest
的大小时也会看到同样的效果。@trashgod我明白了。为什么重复的更新事件会导致这种情况?背后的逻辑是什么?
public class Test extends JPanel implements ActionListener, MouseListener {
private static final long serialVersionUID = 1L;
private static PopUp popUp;
private int stringX = 610;
private int stringCounter = 0;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(600, 600);
Test t = new Test();
t.setBounds(0, 0, 600, 600);
frame.add(t);
t.setVisible(true);
Timer timer = new Timer(5, t);
popUp = new PopUp(100, 100, 400, 400, 100, Color.WHITE);
frame.add(popUp);
popUp.setVisible(true);
timer.start();
frame.addMouseListener(t);
frame.setLayout(null);
frame.setUndecorated(true);
frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, 600, 600);
popUp.draw(g);
g.setColor(Color.WHITE);
g.drawString("This is a test", stringX, 580);
if(++stringCounter % 3 == 0) {
--stringX;
stringCounter = 0;
}
if(stringX == -10 - g.getFontMetrics().stringWidth("This is a test"))
stringX = 610;
}
@Override
public void mouseClicked(MouseEvent e) {
popUp.setExpanding(!popUp.getExpanding());
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
}
setBounds((int) trans.getTranslateX(), (int) trans.getTranslateY(), (int) (width * expansionStage/steps), (int) (height * expansionStage/steps));