JFXPanel заморозил нить AWT второй раз - PullRequest
0 голосов
/ 16 октября 2018

Я в процессе добавления достижений в игру, над которой я работаю, и решил использовать встроенный JavaFX для некоторых дизайнов значков (основное приложение на основе Swing).

Iя создал класс, AchievementMedal, как расширение JFXPanel:

public AchievementMedal(int angle, Color color) 
{
    setSize(200, 200);

    this.finalAngle = angle;
    this.color = color;

    Path p = drawPartialRing(finalAngle);
    Scene scene = new Scene(new Group(p), 180, 180);
    scene.setFill(Color.TRANSPARENT);

    setScene(scene);
}

Для краткости я не включил здесь метод drawPartialRing, но он полностью включен в мою ниже SSCE.Он просто строит Path из вызовов ArcTo, LineTo и MoveTo.

Затем я добавил несколько из них в обычный JPanel и добавил это в основной JFrame моего приложения для отображения.Эта JPanel удаляется и добавляется заново, когда вы уходите, а затем снова возвращаетесь к достижениям.Однако после перехода к нему в секунду времени зависает поток AWT со следующим стеком:

Thread [AWT-EventQueue-0] (Suspended)
    Unsafe.park(boolean, long) line: not available [native method]
    LockSupport.park(Object) line: not available
    CountDownLatch$Sync(AbstractQueuedSynchronizer).parkAndCheckInterrupt()
    CountDownLatch$Sync(AbstractQueuedSynchronizer).doAcquireSharedInterruptibly(int)
    CountDownLatch$Sync(AbstractQueuedSynchronizer).acquireShareInterruptibly(int)
    CountDownLatch.await()
    AchievementMedal(JFXPanel).setScene(Scene) line: 311
    AchievementMedal.<init>(int, Color) line: 20
    AchievementPanel.<init>() line: 32
    JfxSSCE.actionPerformed(ActionEvent) line: 37
    JButton(AbstractButton).fireActionPerformed(ActionEvent)

Мне удалось создать SSCE, который повторяет это.Самое странное, что это абсолютно нормально, если вы удалите только одно из достижений.Таким образом, кажется, что 6 работает совершенно нормально, но как-то 7 это предел!Я попытался повысить мою версию Java (от jre1.8.0_111 до jre1.8.0_181) безрезультатно.Вот мой SSCE (с использованием простых кругов), состоящий из 3 классов:

public class AchievementMedal extends JFXPanel
{
    public AchievementMedal(Color color) 
    {
        setSize(200, 200);

        Circle c = new Circle(90, 90, 85, color);
        Scene scene = new Scene(new Group(c), 180, 180);
        scene.setFill(Color.TRANSPARENT);

        setScene(scene);
    }
}

AchievementPanel, подлежащий обмену и включению, содержащий 7 AchievementMedals (просто удалите любое из выражений «panelGeneral.add ...» длясделайте это волшебным образом):

public class AchievementPanel extends JPanel
{
    public AchievementPanel()
    {
        setPreferredSize(new Dimension(800, 610));
        setLayout(new BorderLayout(0, 0));
        JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP);
        add(tabbedPane, BorderLayout.CENTER);


        tabbedPane.addTab("General", null, panelGeneral, null);

        panelGeneral.add(gray);
        panelGeneral.add(red);
        panelGeneral.add(orange);
        panelGeneral.add(yellow);
        panelGeneral.add(green);
        panelGeneral.add(cyan);
        panelGeneral.add(hotpink);
    }

    private final JPanel panelGeneral = new JPanel();
    private final AchievementMedal gray = new AchievementMedal(Color.GRAY);
    private final AchievementMedal red = new AchievementMedal(Color.RED);
    private final AchievementMedal orange = new AchievementMedal(Color.ORANGE);
    private final AchievementMedal yellow = new AchievementMedal(Color.YELLOW);
    private final AchievementMedal green = new AchievementMedal(Color.LIGHTGREEN);
    private final AchievementMedal cyan = new AchievementMedal(Color.CYAN);
    private final AchievementMedal hotpink = new AchievementMedal(Color.DEEPPINK);
}

Небольшой JFrame, который имитирует поведение замены / использования некоторых основных кнопок:

public class JfxSSCE extends JFrame
                 implements ActionListener
{
public JfxSSCE() 
{
    setSize(800, 600);

    JPanel panel = new JPanel();
    getContentPane().add(panel, BorderLayout.SOUTH);

    panel.add(btnAddPanel);
    panel.add(btnRemovePanel);

    btnRemovePanel.setVisible(false);

    btnAddPanel.addActionListener(this);
    btnRemovePanel.addActionListener(this);
}

private final JButton btnAddPanel = new JButton("Add Panel");
private final JButton btnRemovePanel = new JButton("Remove Panel");
private JPanel panelCenter = new JPanel();

@Override
public void actionPerformed(ActionEvent e)
{
    if (e.getSource() == btnAddPanel)
    {
        panelCenter = new AchievementPanel();
        getContentPane().add(panelCenter, BorderLayout.CENTER);

        btnAddPanel.setVisible(false);
        btnRemovePanel.setVisible(true);
    }
    else
    {
        getContentPane().remove(panelCenter);
        repaint();

        btnAddPanel.setVisible(true);
        btnRemovePanel.setVisible(false);
    }
}


public static void main(String[] args)
{
    JfxSSCE frame = new JfxSSCE();
    frame.setVisible(true);
}
}

Я совершенно не понимаю, что здесь происходит!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...