如何绘制GLCanvas?

时间:2017-03-16 03:27:34

标签: java swing opengl jpanel awt

我希望在3D OpenGL视图上绘制各种各样的HUD,但看起来在我的面板中完成的任何绘图都会被忽略,尽管已经完成了。

这里有一些准系统代码。

MyFrame;

public class MyFrame extends JFrame{
    private static final long serialVersionUID = 1L;
    public MyFrame(Labyrinth l){
        super();
        this.setTitle("My Frame");
        this.setSize(512, 384);
        this.setContentPane(new MyPanel());
        //this.setVisible(true);//If needed here.
    }
}

MyPanel;

public class MyPanel extends JPanel {
    private static final long serialVersionUID = 1L;
    public MyPanel(){
        super();
        this.setLayout(new BorderLayout());
        MyCanvas mc=new MyCanvas(l);
        mc.setFocusable(false);
        this.add(this.mc, BorderLayout.CENTER);
        //this.revalidate();//Doesn't seem needed in the instanciation.
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        this.mc.repaint();
        g.setColor(new Color(128,128,128));
        g.fillRect(0, 0, this.getWidth()/2,this.getHeight()/2); 
        //top-left quarter should be greyed away.
    }
}

MyCanvas;

public class MyCanvas extends GLCanvas{
    private static final long serialVersionUID = 1L;
    public MyCanvas(){
        super(new GLCapabilities(GLProfile.getDefault()));
    }
}

绘画发生,但未在视图中显示。我已经尝试重写repaint(),paint(Graphics),paintComponent(Graphics)和update()。我曾经说过在重量级"重量级"组件很复杂,我应该直接在组件中绘制或使用其他类型。我显然需要GLCanvas来显示3D渲染,同时它似乎不提供绘制叠加层的工具。有人告诉我只需在JFrame的glassPane中绘图,但这看起来有点矫枉过正,而且我被告知永远不要玩玻璃棒,所以我不打算这样做。

我已经看过很多关于绘画电话订单的主题,但是我无法确定哪种方法在覆盖这样或那样的方法时是正确的,我甚至不知道我应该覆盖哪种方法。有没有一种显而易见的方法让我在GLCanvas组件上显示简单的JPanel画作?

2 个答案:

答案 0 :(得分:0)

首先,我真的不建议通过这些手段获得HUD。因为我只能想象这种伤害性能很多。当然,我从来没有尝试过混合使用Java,OpenGL和AWT的图形。

现在不要使用将这些类与胶带一起保存,而是考虑使用JLayeredPane

JLayeredPane layeredPane = new JLayeredPane();

layeredPane.add(new MyCanvas());
layeredPane.add(new MyPanel());

frame.add(layeredPane);

现在重要的是你必须手动设置两个组件的界限:

canvas.setBounds(x, y, width, height);
panel.setBounds(x, y, width, height);

如果不是,您最终会遇到与以前相同的问题:

  

绘画发生,但未在视图中显示

为了证明它有效,我创建了一个类似于TestPanel的小MyPanel类。

public static class TestPanel extends JPanel {
    private Color color;

    public TestPanel(Color color) {
        this.color = color;
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(color);
        g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
    }
}

然后创建两个这样的实例:

JPanel panel1 = new TestPanel(new Color(255, 0, 0));
panel1.setBounds(25, 25, 100, 100);

JPanel panel2 = new TestPanel(new Color(0, 0, 255));
panel2.setBounds(75, 75, 100, 100);

然后将其添加到JLayeredPane并将其添加到JFrame,我们就会看到:

答案 1 :(得分:0)

我发现使用JFrame玻璃面板是一个很好的解决方案,我使用它在3D图形之上绘制调试文本,但是我没有遇到任何问题。使用玻璃面板方法比使用JLayeredPane更方便,因为将为您处理3D面板的大小调整。请注意,必须在GLJPanel组件中绘制3D图形,否则分层将不起作用(与不是Swing组件的GLCanvas相对)。 paintComponent(Graphics g)将以与GLJPanel的帧速率相同的速率被调用。另请注意,默认情况下玻璃窗格是隐藏的,因此必须在其上调用setVisible(true)

import javax.swing.JFrame;
import com.jogamp.opengl.awt.GLJPanel;
// ...

public class ApplicationWindow extends JFrame {
  public ApplicationWindow(String title) {
    super(title);    
    GLCapabilities gl_profile = new GLCapabilities(GLProfile.getDefault());
    GLJPanel gl_canvas = new GLJPanel(gl_profile);
    // ... code here to draw the graphics (supply a GLEventListener to gl_canvas)

    setContentPane(gl_canvas);
    StatusTextOverlayPanel myGlassPane = new StatusTextOverlayPanel();
    setGlassPane(myGlassPane);
    myGlassPane.setVisible(true);
    setVisible(true);
  }

  class StatusTextOverlayPanel extends JComponent {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      g2d.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
      g2d.setPaint(Color.BLACK);
      String statusText = String.format("C-elev: %.2f S-view %.2f D-view %.2f", 1459.0, 17.0, 2.574691);
      g2d.drawString(statusText, 10, 20);
    }
  }
}

以下是其外观示例(您将需要其他代码来绘制所示的轴和正方形)

Java 3D graphics example with overlay text