Necesito lanzar un JFrame desde otro JFrame y hacer que funcione como aplicaciones independientes, ¿me ayuda?

Tengo un JFrame que no se representa de forma activa, a la manera de las aplicaciones Swing básicas estándar, que necesito para iniciar otro JFrame cuando se hace clic en un botón. El segundo JFrame se representa de forma activa utilizando la BufferStrategy de Swing, y se ejecuta de forma independiente; sin embargo, cuando lo llamo desde el otro JFrame ActionPerformed, ambos JFrames se congelan.

Sé que hay complicaciones al usar Swing para lograr este tipo de comportamiento, ¿cómo puedo evitarlos?

Es posible que pueda adaptar este Lanzador basado en Swing que usa ProcessBuilder para ejecutar progtwigs en una JVM separada.

imagen

 package gui; import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; /** * @see http://stackoverflow.com/a/5696404/230513 */ public class Launcher extends JPanel implements Runnable { private final JLabel label = new JLabel(); private final JButton launch = new JButton(); ProcessBuilder pb = new ProcessBuilder( "java", "-cp", "build/classes", "gui.Launcher$DialogTest"); private volatile Process proc; public static void main(String[] args) { EventQueue.invokeLater(new Launcher()::createGUI); } private void createGUI() { final JFrame frame = new JFrame(); frame.setLayout(new GridLayout(0, 1)); frame.add(new Launcher()); frame.add(new Launcher()); frame.add(new Launcher()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } public Launcher() { this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); launch.setAlignmentX(0.5f); label.setAlignmentX(0.5f); launch.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (proc == null) { launch.setText("Terminate"); label.setText("Status: run"); new Thread(Launcher.this).start(); } else { proc.destroy(); reset(); } } }); this.add(launch); this.add(label); reset(); } @Override public void run() { try { proc = pb.start(); proc.waitFor(); } catch (IOException | InterruptedException ex) { ex.printStackTrace(System.err); } EventQueue.invokeLater(this::reset); } private void reset() { proc = null; launch.setText("Launch"); label.setText("Status: idle"); } private static class DialogTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { JOptionPane.showMessageDialog(null, "Running", "Test", JOptionPane.INFORMATION_MESSAGE); System.exit(0); }); } } } 

Actualizado a Java 8 a petición del autor.