【问题标题】:Java JLabel rotated with StackOverflowErrorJava JLabel 使用 StackOverflowError 旋转
【发布时间】:2011-06-16 04:42:16
【问题描述】:

哇...!!

我实际上将我的 JLabel 变量命名为 jll_img 而且我已经在里面设置了一个图标。

我的目的是旋转我将图标放入其中的这个 jlabel。

我通过制作一个按钮来测试它, 然后当单击按钮时,它将按线程旋转。 一个匿名线程,将从 0 度循环到 360 度。

这里

`//我的按钮操作

    new Thread() {

        private boolean doRotating = true;
        private double norm = 0.0;
        private double numbs = 0.0;
        private double degreeIncrementation = 10.0;

        @Override
        public void run() {

            while (doRotating) {

                try {
                    ci = new CompoundIcon(jll_img.getIcon(), new TextIcon(jll_img, ""));
                    if (numbs == 360) {
                        numbs = 0.0;
                        System.err.println("transformed into earlier post");
                        doRotating = false;
                        ri = new RotatedIcon(ci, norm);
                    } else {
                        ri = new RotatedIcon(ci, degreeIncrementation);
                    }

                    System.err.println("degree is " + numbs);
                    jll_img.setIcon(ri);

                    numbs += degreeIncrementation;
                    this.sleep(10);

                    ri = null;
                    ci = null;
                } catch (Exception exp) {
                    System.err.println("blurp!");
                    exp.printStackTrace();
                }

            }

        }
    }.start();`

要进行旋转,我需要 添加另外两个类,即RotatedIcon.javaCompoundIcon.java 因为这两个类主要完成这项工作。

当我尝试单击它直到第 22 次时,不知何故出现此错误。

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.RotatedIcon.getIconHeight(RotatedIcon.java:129) at logic.CompoundIcon.getIconHeight(CompoundIcon.java:211) at logic.CompoundIcon.paintIcon(CompoundIcon.java:229) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233) at logic.RotatedIcon.paintIcon(RotatedIcon.java:175) at logic.CompoundIcon.paintIcon(CompoundIcon.java:233)

这怎么会发生? 如果它可以运行到 21 日……但接下来的 22 日等等最终会失败?

【问题讨论】:

  • 只是对numbs == 360 的评论。永远不要检查浮点值是否相等,而是使用适当的容差(例如Math.abs(numbs-360)<EPS)。此类问题破坏程序的情况很多。

标签: java swing exception rotation jlabel


【解决方案1】:

看起来 RotatedIcon.getIconHeight() 正在调用 CompoundIcon.getIconHeight() ,反之亦然。这是无限递归,会导致堆栈无限增长。

【讨论】:

  • 实际上并不是无限的——只有 88 级左右,这似乎足以耗尽堆栈。
  • @Howard Fine 。 . .没有逻辑限制(即在这种情况下仅受“硬件”或虚拟机限制)
  • 没有。它不会无限递归。与包含在图标中的图标一样多。在这种情况下,它是一个由 22 个图标组成的链。
  • @Howard 啊。我明白了,现在。好电话。
【解决方案2】:

几个cmets:

a) 您无需使用 CompoundIcon。您发布的代码使用空字符串作为 TextIcon。

b) 你不应该嵌套 RotatedIcons。如果嵌套,实际旋转将是所有旋转的总和,因此旋转不会是连续的。如果您嵌套 3 个角度为 1、2、3 的图标,那么您实际上总共旋转了 6 度,而不是 3 度。现在您的代码如下:

RotatedIcon ri = new RotatedIcon(ri, angle);

您应该使用:

RotatedIcon ri = new RotatedIcon(ri.getIcon(), angle);

这是您代码的重组版本,我认为它可以满足您的需求:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class IconSSCCE extends JPanel implements ActionListener
{
    JLabel label = new JLabel();
    TextIcon text;
    ImageIcon image;
    Float angle = 0.0f;

    public IconSSCCE()
    {
        setLayout( new BorderLayout() );

        text = new TextIcon(label, "Some Text", TextIcon.Layout.HORIZONTAL);
//      text = new TextIcon(label, "", TextIcon.Layout.HORIZONTAL);
        image = new ImageIcon("dukeWaveRed.gif");
        CompoundIcon ci = new CompoundIcon(CompoundIcon.Axis.X_AXIS, image, text);
        label.setIcon( ci );
        add(label, BorderLayout.NORTH);

        JButton rotate = new JButton("Rotate");
        add(rotate, BorderLayout.SOUTH);
        rotate.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                new Timer(50, IconSSCCE.this).start();
            }
        });
    }

    public void actionPerformed(ActionEvent e)
    {
        angle++;

        RotatedIcon ri = new RotatedIcon(image, angle);
        CompoundIcon ci = new CompoundIcon(ri, text);
        label.setIcon( ci );
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("IconSSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new IconSSCCE() );
        frame.pack();
        frame.setLocationRelativeTo( null );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

【讨论】:

    【解决方案3】:

    既然不是无限递归,那么在启动JVM时尝试增加堆栈大小:

    java -Xss1m ...
    

    我在这里放了 1 MB,因为在大多数情况下默认值为 512K,但请注意,默认值可能会因您的操作系统而异。检查是什么使您的代码有效。

    此外,请注意您的代码中可能存在的一些严重问题:

    1. 您不应从除 EDT 之外的 Thread 调用 Swing API(在您的情况下为 JLabel.setIcon()getIcon())。要解决这个问题,您可以使用javax.swing.Timer 而不是特定的Thread
    2. if (numbs == 360) 不一定是真的,由于浮点舍入错误,我建议你把它改成if (numbs >= 360.0)

    【讨论】:

      猜你喜欢
      • 2010-12-19
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 1970-01-01
      相关资源
      最近更新 更多