Я в процессе добавления достижений в игру, над которой я работаю, и решил использовать встроенный 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);
}
}
Я совершенно не понимаю, что здесь происходит!