2012-05-16 82 views
11

我有一個問題,可能是由於對Netbeans平臺(7.1.2)或JavaFX 2的某些原理缺乏瞭解導致的。我想將一個JFXPanel加上一個非常簡單的Scene添加到Swing JPanel是TopComponent的子項。我用下面的代碼來實現這一點:爲什麼我的TopComponent上的JavaFX內容會消失?

public accexTopComponent() { 
    initComponents(); 
    setName(Bundle.CTL_accexTopComponent()); 
    setToolTipText(Bundle.HINT_accexTopComponent()); 
    putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); 



    //Begin of my code 
    myFX = new JFXPanel(); //myFX is a static JFXPanel 
    Platform.runLater(new Runnable() { 

     @Override 
     public void run() { 

      myFX.setScene(new Scene(ButtonBuilder.create().minHeight(40.0).minWidth(40.0).build())); 

     } 
    }); 

     jPanel1.add(myFX); 



} 

這編譯沒有問題,一個JavaFX Button顯示,當我告訴了TopComponent的第一次。但只要組件被隱藏並再次顯示,JavaFX Button就會消失,而其他孩子仍然可見。

爲什麼JavaFX內容會消失?

編輯:

我現在包括整個TopComponent的來源。我想這就是你需要自己測試的一切。我沒有更改任何其他文件。

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package de.jeed.nbgan.accexplorer; 

import java.awt.Color; 
import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.scene.Scene; 
import javafx.scene.control.ButtonBuilder; 
import javafx.scene.text.TextBuilder; 
import javafx.scene.web.WebView; 
import javafx.scene.web.WebViewBuilder; 
import org.netbeans.api.settings.ConvertAsProperties; 
import org.openide.awt.ActionID; 
import org.openide.awt.ActionReference; 
import org.openide.windows.TopComponent; 
import org.openide.util.NbBundle.Messages; 

/** 
* Top component which displays something. 
*/ 
@ConvertAsProperties(dtd = "-//de.jeed.nbgan.accexplorer//accex//EN", 
autostore = false) 
@TopComponent.Description(preferredID = "accexTopComponent", 
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS) 
@TopComponent.Registration(mode = "explorer", openAtStartup = true) 
@ActionID(category = "Window", id = "de.jeed.nbgan.accexplorer.accexTopComponent") 
@ActionReference(path = "Menu/Window" /* 
* , position = 333 
*/) 
@TopComponent.OpenActionRegistration(displayName = "#CTL_accexAction", 
preferredID = "accexTopComponent") 
@Messages({ 
    "CTL_accexAction=accex", 
    "CTL_accexTopComponent=Konten-Explorer", 
    "HINT_accexTopComponent=Durchsuchen von Abteilungen und Konten" 
}) 
public final class accexTopComponent extends TopComponent { 

    static JFXPanel myFX; 

    public accexTopComponent() { 
     initComponents(); 
     setName(Bundle.CTL_accexTopComponent()); 
     setToolTipText(Bundle.HINT_accexTopComponent()); 
     putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); 
     myFX = new JFXPanel(); 
     Platform.runLater(new Runnable() { 

      @Override 
      public void run() { 

       myFX.setScene(new       Scene(ButtonBuilder.create().minHeight(40.0).minWidth(40.0).build())); 

     } 
    }); 

     jPanel1.add(myFX); 


} 

/** 
* This method is called from within the constructor to initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is always 
* regenerated by the Form Editor. 
*/ 
// <editor-fold defaultstate="collapsed" desc="Generated Code">       
private void initComponents() { 

    jPanel1 = new javax.swing.JPanel(); 

    jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); 
    jPanel1.setLayout(new java.awt.GridBagLayout()); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 
    this.setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGap(54, 54, 54) 
      .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addContainerGap(153, Short.MAX_VALUE)) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(layout.createSequentialGroup() 
      .addGap(33, 33, 33) 
      .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addContainerGap(74, Short.MAX_VALUE)) 
    ); 
}// </editor-fold>       
// Variables declaration - do not modify      
private javax.swing.JPanel jPanel1; 
// End of variables declaration     

@Override 
public void componentOpened() { 
    // TODO add custom code on component opening 
} 

@Override 
public void componentClosed() { 
    // TODO add custom code on component closing 
} 

void writeProperties(java.util.Properties p) { 
    // better to version settings since initial version as advocated at 
    // http://wiki.apidesign.org/wiki/PropertyFiles 
    p.setProperty("version", "1.0"); 
    // TODO store your settings 
} 

void readProperties(java.util.Properties p) { 
    String version = p.getProperty("version"); 
    // TODO read your settings according to their version 
} 
} 

在我而言,這TopComponent一個名爲AccountExplorer組件它引用的JavaFX,由一個普通的NB平臺應用程序所引用的一部分。

+0

我試圖使用NetBeans 7.1和JavaFX 2.1重現您的問題。所有組件都按預期重新出現。請張貼SSCCE。 – pmoule

+0

感謝您的努力。看我的項目[這裏](https://rapidshare.com/files/894496305/FinancialEngineer.7z) – dajood

+0

對不起,沒有項目下載鏈接,請。爲了讓其他人蔘與並使其更具吸引力,請發佈[SSCCE](http://pscode.org/sscce.html)。 – pmoule

回答

16

試試這個:

Platform.setImplicitExit(false); 
4

我們遇到同樣的問題。基於以下線程,我們假設一旦面板不再可見,JavaFX平臺將自動退出,因爲所有JavaFX GUI元素都不再可見。

這種假設是基於信息:
https://forums.oracle.com/forums/thread.jspa?messageID=10287328
https://forums.oracle.com/forums/thread.jspa?threadID=2390971

第一次嘗試在我們environnment是在代碼中的某個位置添加一個虛擬JFXPanel並保持不變,直到你的程序退出似乎工作。

第二個嘗試在你的代碼也可以工作:

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package de.jeed.nbgan.accexplorer; 

import javafx.application.Platform; 
import javafx.embed.swing.JFXPanel; 
import javafx.geometry.Rectangle2D; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.ButtonBuilder; 
import javafx.scene.paint.Color; 
import javafx.stage.Modality; 
import javafx.stage.Screen; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 
import org.netbeans.api.settings.ConvertAsProperties; 
import org.openide.awt.ActionID; 
import org.openide.awt.ActionReference; 
import org.openide.windows.TopComponent; 
import org.openide.util.NbBundle.Messages; 

/** 
* Top component which displays something. 
*/ 
@ConvertAsProperties(dtd = "-//de.jeed.nbgan.accexplorer//accex//EN", 
autostore = false) 
@TopComponent.Description(preferredID = "accexTopComponent", 
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS) 
@TopComponent.Registration(mode = "explorer", openAtStartup = true) 
@ActionID(category = "Window", id = "de.jeed.nbgan.accexplorer.accexTopComponent") 
@ActionReference(path = "Menu/Window" /* 
* , position = 333 
*/) 
@TopComponent.OpenActionRegistration(displayName = "#CTL_accexAction", 
preferredID = "accexTopComponent") 
@Messages({ 
    "CTL_accexAction=accex", 
    "CTL_accexTopComponent=Konten-Explorer", 
    "HINT_accexTopComponent=Durchsuchen von Abteilungen und Konten" 
}) 
public final class accexTopComponent extends TopComponent { 

    static JFXPanel myFX; 
    static JFXPanel myDummyFXtoKeepJavaFxRunning; 

    public accexTopComponent() { 
     initComponents(); 
     setName(Bundle.CTL_accexTopComponent()); 
     setToolTipText(Bundle.HINT_accexTopComponent()); 
     putClientProperty(TopComponent.PROP_CLOSING_DISABLED, Boolean.TRUE); 
     myFX = new JFXPanel(); 
     myDummyFXtoKeepJavaFxRunning = new JFXPanel(); 
     Platform.runLater(new Runnable() { 

      @Override 
      public void run() { 
       // Actual FX code that will be hidden/shown 
       myFX.setScene(new Scene(ButtonBuilder.create().minHeight(40.0).minWidth(40.0).build())); 

       // Workaround 
       Stage dummyPopup = new Stage(); 
       dummyPopup.initModality(Modality.NONE); 
       // set as utility so no iconification occurs 
       dummyPopup.initStyle(StageStyle.UTILITY); 
       // set opacity so the window cannot be seen 
       dummyPopup.setOpacity(0d); 
       // not necessary, but this will move the dummy stage off the screen 
       final Screen screen = Screen.getPrimary(); 
       final Rectangle2D bounds = screen.getVisualBounds(); 
       dummyPopup.setX(bounds.getMaxX()); 
       dummyPopup.setY(bounds.getMaxY()); 
       // create/add a transparent scene 
       final Group root = new Group(); 
       dummyPopup.setScene(new Scene(root, 1d, 1d, Color.TRANSPARENT)); 
       // show the dummy stage 
       dummyPopup.show(); 

       // size back to scene size 
       dummyPopup.sizeToScene(); 

       // if you centered it before hiding 
       //dummyPopup.centerOnScreen();  
      } 
     }); 

     jPanel1.add(myFX); 
    } 

    /** 
    * This method is called from within the constructor to initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is always 
    * regenerated by the Form Editor. 
    */ 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     jPanel1 = new javax.swing.JPanel(); 

     jPanel1.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED)); 
     jPanel1.setLayout(new java.awt.GridBagLayout()); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 
     this.setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(54, 54, 54) 
       .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(153, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(33, 33, 33) 
       .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(74, Short.MAX_VALUE)) 
     ); 
    }// </editor-fold>       
    // Variables declaration - do not modify      
    private javax.swing.JPanel jPanel1; 
    // End of variables declaration     

    @Override 
    public void componentOpened() { 
     // TODO add custom code on component opening 
    } 

    @Override 
    public void componentClosed() { 
     // TODO add custom code on component closing 
    } 

    void writeProperties(java.util.Properties p) { 
     // better to version settings since initial version as advocated at 
     // http://wiki.apidesign.org/wiki/PropertyFiles 
     p.setProperty("version", "1.0"); 
     // TODO store your settings 
    } 

    void readProperties(java.util.Properties p) { 
     String version = p.getProperty("version"); 
     // TODO read your settings according to their version 
    } 
} 
+0

我沒有希望了。非常感謝你,這對我來說真的很有幫助。 – dajood

+5

真正的修復應該在javaFX 2.2請參閱http://javafx-jira.kenai.com/browse/RT-15011一個應該使用Platform.setImplicitExit(布爾implicitExit)。 – Escay

1

我就死在了同樣的問題: 我確實有這個問題不僅與頂部的組件。 ..但也與我的模態對話窗口。在一些操作系統上,他們似乎首先在其他操作系統(Windows)上工作,對話框以黑色的空盒子(linux)開始。在對話框中(通常在點擊按鈕之後),在對話框中(在Windows下),對話框也變空(通常在第六次點擊之後)。 當他們重新出現(但不是其他部分)按鈕時移動鼠標(而不是點擊)

我也有效果(至少在windows下)最小化和恢復主窗口結果在一個空的窗口。

但是:(!!!!!) 我發現使用鼠標調整主窗口或對話框的大小可以恢復內容! 所以我假設你的假設與prelimanary死亡不能是原因(爲什麼它應該回來)。

對於對話框我找到了解決辦法: 使該窗口的場景中的類成員,因此您可以在以下重繪日後訪問()方法:

/** 
    * force repaint by re-setting the scene 
    * This solves a repainting bug in JavaFx 1.8.05 
    */ 
    private void repaint(){ 
    setScene(null); 
    Platform.runLater(new Runnable() { 
     @Override 
     public void run() { 
     setScene(scene); 
     } 
    }); 
    } 

在對話框中我使用重繪( )在showModal()之前和每個按鈕事件結束時 - >正常工作:-) 但是我沒有找到一個事件,我可以在主窗口最小化之後調用repaint()。 現在一個新的神祕的,但一個解決方案: 如果我把重新調整()在show()之前的MainWindow它一切正常。我不知道爲什麼......

但我絕對認爲這是所有關於JavaFX中的錯誤,希望在下一個版本中修復。

問候

英戈

相關問題