我正在为正在开发的游戏添加成就,因此决定将嵌入式JavaFX用于某些徽章设计(主要应用程序基于Swing)。
我创建了一个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中。它只是通过ArcTo,LineTo和MoveTo调用构建路径。
然后,我将其中几个添加到常规JPanel中,并将其添加到应用程序的主JFrame中进行显示。当您离开并再次返回到Achievements时,将删除并重新添加此JPanel。但是,在导航到 second 时,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);
}
}
我对这里发生的事情一无所知!