我遇到的问题可能是由于缺乏对Netbeans平台(7.1.2)或JavaFX 2的一些原则的理解。我想添加一个非常简单的JFXPanel
{ {1}}到作为TopComponent的子项的Swing Scene
。我通过以下代码实现了这个目标:
JPanel
编译没有问题,当我第一次显示 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
。但是只要组件被隐藏并再次显示,JavaFX TopComponent
就会消失,而其他孩子仍然可见。
为什么JavaFX内容会消失?
编辑:
我现在包含整个TopComponent的源代码。我想这就是你需要自己测试的全部内容。我没有更改任何其他文件。
Button
在我的例子中,这个/*
* 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
}
}
是一个名为AccountExplorer的组件的一部分,它引用了JavaFX并被一个普通的NB平台应用程序引用。
答案 0 :(得分:20)
试试这个:
Platform.setImplicitExit(false);
答案 1 :(得分:4)
我们遇到了同样的问题。基于以下线程,我们假设一旦面板不再可见,JavaFX平台将自动退出,因为所有JavaFX gui元素都不再可见。
该假设基于以下信息:
https://forums.oracle.com/forums/thread.jspa?messageID=10287328和
https://forums.oracle.com/forums/thread.jspa?threadID=2390971
在我们的环境中进行的第一次尝试是在代码中的某处添加一个虚拟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
}
}
答案 2 :(得分:1)
我遇到了同样的问题: 我不仅有顶级组件的问题,而且还有我的模态对话窗口。在某些操作系统上,它们似乎首先(Windows)在其他操作系统上工作,对话框从一个黑色的空盒子(linux)开始。在使用对话框(通常在单击按钮后)的某些对话框(在Windows下)时,对话框也会变空(通常在第六次单击后左右)。 当鼠标移动(不点击)时,它们重新出现(但不是其余的)
我也有效果(至少在windows下),最小化和恢复主窗口会产生一个空窗口。
但是:(!!!!!) 我发现调整主窗口的大小或用鼠标对话框会带回内容! 因此,我认为你对先前死亡的假设不是原因(为什么它应该回来)。
对于Dialogs我找到了一个解决方案: 使窗口的场景成为类成员,以便稍后在以下repaint()方法中访问它:
/**
* 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() - &gt;工作良好 :-) 但我发现了一个事件,我可以在最小化主窗口后调用repaint()。 现在是一个新的神秘但解决方案: 如果我将show()放在MainWindow的show()之前,它一切正常。我不知道为什么......
但我绝对认为这完全是关于JavaFX中的一个错误,希望将在下一个版本中修复。
祝你好运
英戈