JME 3 + Swing, несколько холстов

Я играю с JME3 и в настоящее время сталкиваюсь со следующей проблемой:

Когда холсты LWJGL включены в несколько вкладок приложения, не запускается ни одна из них или только 1.

Вот пример:

SwingCanvas.java:

package jme3test.helloworld;

import java.awt.Dimension;
import javax.swing.JFrame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;

public class SwingCanvas extends SimpleApplication {

    private void SwingCanvasTest() {
        SwingCanvas app = new SwingCanvas();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        // activate windowed input behaviour
        flyCam.setDragToRotate(true);

        Box box = new Box(2, 2, 2);
        Geometry geom = new Geometry("Box", box);
        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat.setColor("Color", ColorRGBA.Blue);
        geom.setMaterial(mat);

        rootNode.attachChild(geom); // make the cube appear in the scene
    }

    public JmeCanvasContext createJMEcanvas(){
        AppSettings settings = new AppSettings(true);
        settings.setWidth(640);
        settings.setHeight(480);

        this.setSettings(settings);
        this.createCanvas(); // create canvas!

        JmeCanvasContext ctx = (JmeCanvasContext) this.getContext();
        ctx.setSystemListener(this);
        Dimension dim = new Dimension(640, 480);
        ctx.getCanvas().setPreferredSize(dim);

        return ctx;
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {

                SwingCanvas canvasApplication = new SwingCanvas();

                JFrame window = new JFrame("Swing Application");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                window.add(canvasApplication.createJMEcanvas().getCanvas());
                window.pack();
                window.setVisible(true);

                canvasApplication.start();              
            }
        });
    }
}

SwingApplicationJME.java:

package jme3test.helloworld;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;

import com.jme3.system.JmeCanvasContext;

public class SwingApplicationJME {

    public SwingApplicationJME(){
        JFrame frame = new JFrame("JME Swing Application");
        frame.setSize(800, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getLayout());
        frame.setVisible(true);
    }

    private JComponent getLayout(){
        JTabbedPane tabbedPane = new JTabbedPane();

        SwingCanvas canvas1 = new SwingCanvas();
        SwingCanvas canvas2 = new SwingCanvas();
        SwingCanvas canvas3 = new SwingCanvas();

        JmeCanvasContext ctx1 = canvas1.createJMEcanvas();
        JmeCanvasContext ctx2 = canvas2.createJMEcanvas();
        JmeCanvasContext ctx3 = canvas3.createJMEcanvas();

        JPanel JME_panel_1 = new JPanel(new BorderLayout());
        JME_panel_1.add(new JButton("WEST"), BorderLayout.WEST);
        JME_panel_1.add(new JButton("NORTH"), BorderLayout.NORTH);
        JME_panel_1.add(new JButton("EAST"), BorderLayout.EAST);
        JME_panel_1.add(new JButton("SOUTH"), BorderLayout.SOUTH);
        JME_panel_1.add(ctx1.getCanvas(), BorderLayout.CENTER);

        JPanel JME_panel_2 = new JPanel();
        JSplitPane splitPaneVertical = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
        splitPaneVertical.add(new JButton("Vertical Button"), JSplitPane.LEFT);
        splitPaneVertical.add(ctx2.getCanvas(), JSplitPane.RIGHT);
        JME_panel_2.add(splitPaneVertical);

        JPanel JME_panel_3 = new JPanel();
        JSplitPane splitPaneHorizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPaneHorizontal.add(new JButton("Horizontal Button"), JSplitPane.TOP);
        splitPaneHorizontal.add(ctx3.getCanvas(), JSplitPane.BOTTOM);
        JME_panel_3.add(splitPaneHorizontal);

        tabbedPane.add(JME_panel_1, "JME border panel");
        tabbedPane.add(JME_panel_2, "JME vetical split panel");
        tabbedPane.add(JME_panel_3, "JME horizontal split panel");

        return tabbedPane;
    }

    public static void main(String [] s){
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                SwingApplicationJME app = new SwingApplicationJME();
            }
        });
    }
}

Любые идеи, пожалуйста =)


person sergpank    schedule 12.04.2012    source источник
comment
Может быть, вам нужен отдельный поток для каждого Canvas? Просто дикая мысль, однако.   -  person Jakub Zaverka    schedule 12.04.2012
comment
Возможно, просто подумал, что они уже находятся в отдельных потоках: private void SwingCanvasTest() { SwingCanvas app = new SwingCanvas(); приложение.старт(); }   -  person sergpank    schedule 13.04.2012


Ответы (1)


Нашел удобное решение в документации jmonkeyengine: Monkey canvas + Графический интерфейс Swing

вот цитата кода:

final JMenuItem itemSwitchTab = new JMenuItem("Switch to tab #2");
    menuTortureMethods.add(itemSwitchTab);
    itemSwitchTab.addActionListener(new ActionListener(){
       public void actionPerformed(ActionEvent e){
           if (itemSwitchTab.getText().equals("Switch to tab #2")){
               canvasPanel1.remove(canvas);
               canvasPanel2.add(canvas, BorderLayout.CENTER);
               currentPanel = canvasPanel2;
               itemSwitchTab.setText("Switch to tab #1");
           }else if (itemSwitchTab.getText().equals("Switch to tab #1")){
               canvasPanel2.remove(canvas);
               canvasPanel1.add(canvas, BorderLayout.CENTER);
               currentPanel = canvasPanel1;
               itemSwitchTab.setText("Switch to tab #2");
           }
       } 
    });

Все что нам нужно убрать холст с одной вкладки и добавить на другую.

person sergpank    schedule 23.11.2012