Java JLabel вращается с помощью StackOverflowError - PullRequest
1 голос
/ 16 июня 2011

WAW ... !!

У меня фактически есть переменная JLabel с именем jll_img И я уже установил значок в нем.

Моя цель состоит в том, чтобы повернуть этот ярлык, в который я поместил значок.

Я проверяю это, делая один BUtton, и затем, когда кнопка будет нажата, она будет вращаться потоком. Один анонимный поток, который будет выполнять цикл от 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.java и CompoundIcon.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-й и т. д. в конечном итоге потерпит неудачу?

Ответы [ 3 ]

4 голосов
/ 16 июня 2011

Похоже, что RotatedIcon.getIconHeight () вызывает CompoundIcon.getIconHeight () и наоборот.Это бесконечная рекурсия, которая заставляет стек расти без ограничений.

2 голосов
/ 16 июня 2011

Несколько комментариев:

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();
            }
        });
    }
}
1 голос
/ 16 июня 2011

Поскольку это не бесконечная рекурсия, попробуйте увеличить размер стека при запуске JVM:

java -Xss1m ...

Я поместил 1 МБ здесь, поскольку по умолчанию 512 КБ в большинстве ситуаций, но имейте в виду, чтозначение по умолчанию может отличаться в зависимости от вашей ОСПроверьте, что заставляет ваш код работать.

Кроме того, обратите внимание на несколько потенциально серьезных проблем в вашем коде:

  1. Вы не должны вызывать Swing API (JLabel.setIcon() и getIcon()в вашем случае) от Thread, кроме EDT.Чтобы решить эту проблему, вы можете использовать javax.swing.Timer вместо определенного Thread.
  2. if (numbs == 360) не обязательно может быть истинным, из-за ошибок округления с плавающей запятой, я бы предложил вам изменить его на if (numbs >= 360.0)
...