我需要从另一个JFrame启动一个JFrame,让它像独立的应用程序一样运行,有帮助吗? [英] I need to launch a JFrame from another JFrame and have that run like independent applications, help?

查看:89
本文介绍了我需要从另一个JFrame启动一个JFrame,让它像独立的应用程序一样运行,有帮助吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个没有主动渲染的JFrame,一个标准的基本Swing应用程序,我需要在单击一个按钮时启动另一个JFrame。第二个JFrame使用Swing的BufferStrategy进行主动渲染,并独立运行 - 但是,当我从其他JFrame的ActionPerformed中调用它时,两个JFrame都会冻结。



我知道使用Swing来完成这种行为很复杂 - 我怎么能绕过它们?

解决方案

您可以根据

  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
* /
公共类Launcher扩展JPanel实现Runnable {

私人最终JLabel标签=新JLabel();
私人决赛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 (终止);
label.setText(状态:运行);
新线程(Launcher.this).start();
} else {
proc。 destroy();
reset();
}
}
});
this.add(发布);
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(状态:空闲);
}

私有静态类DialogTest {

public static void main(String [] args){
EventQueue.invokeLater(() - > {
JOptionPane.showMessageDialog(null,Running,
Test,JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
});
}
}
}

根据作者的要求更新到Java 8.


I have one JFrame that's not actively rendered, a la standard basic Swing applications, which I need to launch another JFrame when a button is clicked. The second JFrame is actively rendered using Swing's BufferStrategy, and runs on its own independently - however, when I call it from the other JFrame's ActionPerformed both JFrames freeze.

I know there are complications in using Swing to accomplish this kind of behavior - how can I get around them?

解决方案

You might be able to adapt this Swing based Launcher that uses ProcessBuilder to run programs in a separate JVM.

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);
            });
        }
    }
}

Updated to Java 8 at the author's request.

这篇关于我需要从另一个JFrame启动一个JFrame,让它像独立的应用程序一样运行,有帮助吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆