package com.chuangzhou.vivid2D.test; import com.chuangzhou.vivid2D.render.awt.ModelClickListener; import com.chuangzhou.vivid2D.render.awt.ModelLayerPanel; import com.chuangzhou.vivid2D.render.awt.ModelRenderPanel; import com.chuangzhou.vivid2D.render.model.Model2D; import com.chuangzhou.vivid2D.render.model.ModelPart; import com.chuangzhou.vivid2D.render.model.util.Mesh2D; import javax.swing.*; import java.awt.*; /** * 简单的测试示例:创建一个 Model2D,添加几层(部件), * 然后在 JFrame 中展示 ModelLayerPanel(左侧)、ModelRenderPanel(中间渲染区) * 和模型树(右侧)以便观察变化。 */ public class ModelLayerPanelTest { public static void main(String[] args) { SwingUtilities.invokeLater(() -> { // 创建示例模型并添加图层 Model2D model = new Model2D("示例模型"); // 调整一些初始属性(可选) ModelPart person = model.getPart("人物"); if (person != null) { try { person.setOpacity(0.85f); } catch (Exception ignored) {} } // 创建 UI JFrame frame = new JFrame("ModelLayerPanel 测试(含渲染面板)"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.setLayout(new BorderLayout()); // 左侧:图层面板(传入 renderPanel 后可在面板中绑定贴图到 GL 上下文) // 先创建一个占位 renderPanel,再把它传给 layerPanel(ModelRenderPanel 构造需要尺寸) ModelRenderPanel renderPanel = new ModelRenderPanel(model, 640, 480); //renderPanel.addModelClickListener(new ModelClickListener() { // @Override // public void onModelClicked(Mesh2D mesh, float modelX, float modelY, int screenX, int screenY) { // if (mesh == null) return; // System.out.println("点击了模型:" + mesh.getName() + ",模型坐标:" + modelX + ", " + modelY + ",屏幕坐标:" + screenX + ", " + screenY); // } //}); ModelLayerPanel layerPanel = new ModelLayerPanel(model, renderPanel); layerPanel.setPreferredSize(new Dimension(260, 600)); frame.add(layerPanel, BorderLayout.WEST); // 中间:渲染面板 renderPanel.setPreferredSize(new Dimension(640, 480)); frame.add(renderPanel, BorderLayout.CENTER); // 右侧:显示模型树(用于观察当前模型部件结构) JTree tree = new JTree(model.toTreeNode()); JScrollPane treeScroll = new JScrollPane(tree); treeScroll.setPreferredSize(new Dimension(240, 600)); frame.add(treeScroll, BorderLayout.EAST); // 底部:演示按钮(刷新树以反映面板中对模型的更改) JPanel bottom = new JPanel(new FlowLayout(FlowLayout.LEFT)); JButton refreshBtn = new JButton("刷新模型树"); refreshBtn.addActionListener(e -> { tree.setModel(new javax.swing.tree.DefaultTreeModel(model.toTreeNode())); for (int i = 0; i < tree.getRowCount(); i++) tree.expandRow(i); // 同步通知渲染面板(如果需要)去刷新模型 try { renderPanel.setModel(model); } catch (Exception ignored) {} }); bottom.add(refreshBtn); JButton printOrderBtn = new JButton("打印部件顺序(控制台)"); printOrderBtn.addActionListener(e -> { System.out.println("当前模型部件顺序:"); for (ModelPart p : model.getParts()) { System.out.println(" - " + p.getName() + " (可见=" + p.isVisible() + ", 不透明度=" + p.getOpacity() + ")"); } }); bottom.add(printOrderBtn); frame.add(bottom, BorderLayout.SOUTH); // 监听窗口关闭,确保释放 GL 资源 frame.addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(java.awt.event.WindowEvent e) { // 先释放渲染面板相关 GL 资源与线程 try { renderPanel.dispose(); } catch (Throwable t) { t.printStackTrace(); } } @Override public void windowClosed(java.awt.event.WindowEvent e) { // 进程退出(确保彻底关闭) try { renderPanel.dispose(); } catch (Throwable ignored) {} System.exit(0); } }); frame.setSize(1200, 700); frame.setLocationRelativeTo(null); frame.setVisible(true); }); } }