I have a large Java swing-based application and needed to add a text editor. The JavaFX HTML editor appears to be my best option. I am hoping to have the HTML Editor in a JPanel aside other controls in the Swing environment. I can do this but I must not be closing the JavaFX HTML Editor correctly because I can only get the HTML Editor to run once unless I exit the entire larger program. The first time I open the Editor app the Platform.runLater() executes. The second call to the Editor app does not run the Platform.runLater(). I have included code for the "calling" program with 2 buttons. Each button calls the Editor code. The first button click opens the editor correctly. Clicking a second time opens the Swing window but the HTML Editor is not loaded. The second code is for the program that opens a Swing frame and tries to load the JavaFX HTML Editor into a JPanel in the JFrame. This is on a Windows machine and NetBeans is my IDE. Thanks for any help you can offer.
Doug
calling program
package testjavafxeditorswingcaller;
import testhtmleditorminimal.TestHTMLeditorMinimal;
/**
*
* @author DStockman
*/
public class NewJFrame extends javax.swing.JFrame {
/**
* Creates new form NewJFrame
*/
public NewJFrame() {
initComponents();
}
/**
* 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.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
call1PB = new javax.swing.JButton();
call2PB = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
call1PB.setText("Call1");
call1PB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
call1PBActionPerformed(evt);
}
});
call2PB.setText("Call2");
call2PB.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
call2PBActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(163, 163, 163)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(call2PB)
.addComponent(call1PB))
.addContainerGap(165, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(57, 57, 57)
.addComponent(call1PB)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(call2PB)
.addContainerGap(193, Short.MAX_VALUE))
);
setSize(new java.awt.Dimension(416, 308));
setLocationRelativeTo(null);
}// </editor-fold>
private void call1PBActionPerformed(java.awt.event.ActionEvent evt) {
TestHTMLeditorMinimal a1 = new TestHTMLeditorMinimal();
a1.main(null);
a1.setVisible(true);
}
private void call2PBActionPerformed(java.awt.event.ActionEvent evt) {
TestHTMLeditorMinimal a2 = new TestHTMLeditorMinimal();
a2.main(null);
a2.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton call1PB;
private javax.swing.JButton call2PB;
// End of variables declaration
}
Editor program
package testhtmleditorminimal;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.web.HTMLEditor;
import javafx.scene.web.WebView;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* @author DStockman
*/
public class TestHTMLeditorMinimal extends JApplet {
private static final int JFXPANEL_WIDTH_INT = 1200;
private static final int JFXPANEL_HEIGHT_INT = 1000;
private static JFXPanel fxContainer;
public static HTMLEditor htmlEditor=null;
public static Scene scene = null;
public static JFrame frame=null;
public static JApplet applet=null;
public static JPanel jpanel=null;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception e) {
}
frame = new JFrame("JavaFX 2 in Swing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
applet = new TestHTMLeditorMinimal();
applet.init();
frame.setContentPane(applet.getContentPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
applet.start();
}
});
}
@Override
public void init() {
jpanel = new JPanel();
fxContainer = new JFXPanel();
fxContainer.setPreferredSize(new Dimension(JFXPANEL_WIDTH_INT, JFXPANEL_HEIGHT_INT));
jpanel.add(fxContainer);
add(jpanel, BorderLayout.CENTER);
Platform.runLater(new Runnable() {
@Override
public void run() {
createScene();
}
});
}
private void createScene() {
htmlEditor = new HTMLEditor();
htmlEditor.setHtmlText("Testing");
addToolBar();
scene = new Scene(htmlEditor);
fxContainer.setScene(scene);
} // ********************************************
public void addToolBar(){
Node toolNode = htmlEditor.lookup(".top-toolbar");
Node webNode = htmlEditor.lookup(".web-view");
if (toolNode instanceof ToolBar && webNode instanceof WebView) {
ToolBar bar = (ToolBar) toolNode;
WebView webView = (WebView) webNode;
//engine = webView.getEngine();
Button btnCaretExit = new Button("Close");
bar.getItems().addAll(btnCaretExit);
// I tried multiple ways to exit program
btnCaretExit.setOnAction((ActionEvent event) -> {
Platform.setImplicitExit(true);
applet.destroy();
fxContainer.removeAll();
Platform.exit();
frame.dispose();
});
}
}
}
Thanks for the suggestions! I got rid of the JApplet. I continued to test various ways to close the code with the HTMLEditor in it but the HTMLEditor would still not reinitialize when a second start of the code was attempted (without shutting down the calling program). The only way I could get the program to work was your suggestion of: frame.setVisible(false); I tried a couple different methods to re-open the hidden app. What I am doing right now from the calling program is:
// calling program
public WebViewTest a1=null;
if(a1 == null){
a1 = new WebViewTest();
a1.initAndShowGUI("Starting 2", 900,900);
}
else{
a1.initAndShowGUI("Starting 2 restart", 900,900);
// when I used the following I got an error with .setContent
//a1.setVisible();
//a1.setContent("Selected Call 2");
}
// in the editor program
// does not work
public void setContent(String content){
htmlEditor.setHtmlText(content);
}
Is the above method going to keep creating new (quasi)instances of the code every time it is opened because of the repeated calls to initAndShowGUI? Sorry for my ignorance on the basics of Java functioning.
Thanks again! Doug