1

嗨,我想分享我的 Warkaround 来解决一个我花了几个小时才解决的问题,因为我找不到任何直截了当的答案。

我正在实现一个 Swing 应用程序,该应用程序根据其状态显示 JavaFX 图表(实时折线图)或其他一些内容(在我的情况下是 JFreeChart)。我正在向我的 UI 添加和删除面板,但它适用于大多数内容。

使用 JavaFX 时,我的内容一旦可见然后隐藏就不会显示。

请参阅下面的非工作示例代码:

CustomFXPanel pn1 = new CustomFXPanel(); //JPanel containing JavaFX Chart
CustomPanel pn2 = new CustomPanel();     //Extends JPanel
JPanel pnContent; //PlaceHolder for either Panel



/**
 * Constructor
 */
public MyJFrame(){
    init(); //Set up JFrame Size, title etc.
    setLayout(new GridLayout(1,1)); //Show the Content all across the Frame
    pnContent = pn1;
    add(pnContent);
}    

/**
 * Changes Mode of Application
 * @param showFX: True = show fxChart, False = show other Panel
 */
public void changePanel(boolean showFX){
    if(showFX){  //Show FX Chart
        if(!pnContent.equals(pn1)){
            remove(pnContent);
            pnContent = pn1;
            add(pnContent);
        }
    }else{  //Show other Panel
        if(!pnContent.equals(pn2)){
            remove(pnContent);
            pnContent = pn2;
            add(pnContent);
        }
    }
}

问题: 启动时显示正常。但是,当更改为 pn2 然后又回到 pn1 时,pn1 中的 JFXPanel 根本不会出现。

我通过在 pn1 中调用 myFXPanel.setStage(new Stage(myJFXChart)) 使其工作。然而,这总是抛出一个 IllegalArgumentsException,...“已经设置为另一个场景的根”。- 它有效,但我认为让异常到处乱飞是丑陋和不好的做法。

令人讨厌的是,任何处理此异常的尝试都导致小组不再出现。这包括:

JFXPanel myFXPanel = new JFXPanel();
LineChart<Number, Number> chart;
....
//Inside reload method
//With parts inside then outside Platform.runLater(new Runnable()) {...}
myFXPanel.invalidate();
myFXPanel.removeAll();
try{
    setStage(newStage(chart));
}catch(Exception ex){}
4

1 回答 1

1

我能找到的唯一解决方法是滥用 JSplitPane(setDivider(0) 并将任一侧设置为 setVisible(false)):示例代码如下。

CustomFXPanel pn1 = new CustomFXPanel(); //JPanel containing JavaFX Chart
CustomPanel pn2 = new CustomPanel();     //Extends JPanel
JSplitPane spContent;
…
/**
 * Constructor
 */
public MyJFrame(){
    init(); //Set up JFrame Size, title etc.
    spContent.setDividerSize(0);        //Hide the Divider
    spContent.setLeftComponent(pn1);    
    spContent.setLeftComponent(pn2);
    pn1.setVisible(true);               //By default show pn1
    pn2.setVisible(false);              //Hide this Panel. JSplitPane will adjust itself (either left or right will take up all space).

    setLayout(new GridLayout(1,1)); //Show the Content all across the Frame
    add(spContent);
}    

/**
 * Changes Mode of Application
 * @param showFX: True = show fxChart, False = show other Panel
 */
public void changePanel(boolean showFX){
    if(showFX){  //Show FX Panel
        pn1.setVisible(true);    //spContent will adjust itself
        pn2.setVisible(false);
    }else{  //Show normal Panel
        pn1.setVisible(false);
        pn2.setVisible(true);
    }
}

如果你们中的任何人找到更优雅的解决方案,请随时写下您的答案。我认为我在这里写了自己的解决方法,我不是唯一一个遇到/遇到这个问题的人。

我希望我能帮上忙。干杯

于 2013-05-28T11:23:57.383 回答