当前位置: 首页 > 知识库问答 >
问题:

多个面板/画布

许彭祖
2023-03-14

我正在寻找一种在面板/面板或画布之间进行日常切换的方法。更具体地说:我正在开发一个游戏。在我的代码中,有一个类扩展了canvas并实现了Runnable,在游戏的构造函数中,它创建了一个名为window的类的新实例。这是窗口类:

public class Window extends Canvas {
private static final long serialVersionUID = -299686449326748512L;

public static JFrame frame = new JFrame();

public Window(int width, int height, String title, Game game) {
   // JFrame frame = new JFrame();
    frame.setPreferredSize(new Dimension(width, height));
    frame.setMaximumSize(new Dimension(width, height));
    frame.setMinimumSize(new Dimension(width, height));
    frame.setTitle(title);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.add(game);
    frame.setVisible(true);
    game.start();
 }
}

我想能够删除帧的游戏,激活另一个面板,并停止执行游戏。我已经试过:

game.stop();
Window.frame.remove(game);

但它使程序崩溃。这些是start()

/**
 * starts the game.
 */
public synchronized void start() {
    thread = new Thread(this);
    thread.start();
    running = true;
}
 /**
 * tries to stop the game.
 */
public synchronized void stop() {
    try {
        thread.join();
        running = false;
    } catch (Exception e) {
        e.printStackTrace();
    }
}

我的主要目标是能够在发生某些事件时播放一个剪接场景,我正尝试使用vlcj来实现这一目的。如果有人有一个想法可以让我实现这个目标,那也太好了。

共有1个答案

白昊东
2023-03-14

我已经做了一个例子,做我认为你想要的没有卡片布局,并使用线程。我认为这是一个概念的证明,你的要求是可能的。下面,我将包括一些我会做的事情来改进它。

import javax.swing.*;
import java.awt.*;
public class SwapCards{
    Thread gameLoop;
    volatile boolean running = false;
    double x = 0;
    double y = 0;
    double theta = 0;
    JFrame frame = new JFrame("swapped");        
    Canvas gamePanel = new Canvas(){
        public void paint(Graphics g){
            super.paint(g);
            g.setColor(Color.BLACK);
            g.drawOval((int)x, (int)y, 25, 25);
        }
    };
    Canvas nonGame = new Canvas(){
        public void paint(Graphics g){
            super.paint(g);
            g.setColor(Color.BLUE);
            g.fillRect(0,0,200, 200);
        }
    };
    public void step(){
        x = 100 + 50*Math.sin( theta );
        y = 100 + 50*Math.cos( theta );
        theta += 0.02;
        if(theta > 6.28) theta = 0;
    }

    public void startGameLoop(){
        frame.remove(nonGame);
        frame.add(gamePanel, BorderLayout.CENTER);
        frame.validate();
        running = true;
        gameLoop = new Thread(()->{
            while(running){
                step();
                gamePanel.repaint();
                try{
                    Thread.sleep(30);
                }catch (Exception e){
                    running = false;
                    throw new RuntimeException(e);
                }
            }
        });
        gameLoop.start();
    }
    public void stopGameLoop(){
        frame.remove(gamePanel);
        frame.add(nonGame, BorderLayout.CENTER);
        running = false;
        try{
            gameLoop.join();
        } catch(Exception e){
            throw new RuntimeException(e);
        }
    }
    public void buildGui(){
        JButton button = new JButton("action");
        button.addActionListener( evt->{
           if(!running){
               startGameLoop();
           } else{
               stopGameLoop();
           }
        });
        frame.add(nonGame, BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);
        frame.setSize(400, 400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
    public static void main(String[] args){
        EventQueue.invokeLater( new SwapCards()::buildGui );
    }
}

首先,Canvas有些过时了,请使用JPane并覆盖PapComponent。这让你更容易获得挥杆的力量。

在这个例子中,我正在做一些琐碎的工作,所以线程绝对是多余的,我可以用javax来代替它。摆动定时器

    Timer timer = new Timer(30, evt->{
       step(); 
       gamePanel.repaint();
    });

然后在start和stop方法中,我只调用计时器。start()计时器。分别停止()。

使用CardLayout可以更清楚地了解您想要做什么,此外,它还提供了导航卡片的方法。如果你有一个带有一系列你想显示的组件的剪切场景,你可以使用cardLayout。下一个(父级)

当我们创建布局时:

cards = new CardLayout();
swap = new JPanel(cards);
swap.add(gamePanel, "game");
swap.add(nonGame, "nogame");
cards.last(swap);
frame.add(swap, BorderLayout.CENTER);

这将把卡片添加到交换中,并使其显示noplay。然后在开始/停止方法中,我们只需切换到相应的卡。

cards.show(swap, "game");

 类似资料:
  • 画板概述 画板表示可以包含可打印图稿的区域。可以将画板作为裁剪区域以满足打印或置入的需要,这些画板与 Illustrator CS3 中的裁剪区域的作用相同。可以使用多个画板来创建各种内容,例如,多页 PDF、大小或元素不同的打印页面、网站的独立元素、视频故事板或者组成 Adobe Flash 或 After Effects 中的动画的各个项目。 注:如果在 Illustrator CS3 文档中

  • 画板可帮助简化您的设计过程,它提供了一个区域,您可以在该区域内布置适合不同设备和屏幕的设计。画板表示可以包含可打印或可导出图稿的区域。创建画板时,您可以从各种预设大小中进行选取,也可以定义自己的自定画板大小。 每个文档中可以容纳的画板数为 1 到 1000 个,具体数量取决于画板的大小。您可以在最初创建文档时指定文档的画板数,并且在处理文档的过程中,可以随时添加和删除画板。您可以创建大小不同的画板

  • 画板可帮助简化您的设计过程,它提供了一个区域,您可以在该区域内布置适合不同设备和屏幕的设计。画板表示可以包含可打印或可导出图稿的区域。创建画板时,您可以从各种预设大小中进行选取,也可以定义自己的自定画板大小。 每个文档中可以容纳的画板数为 1 到 1000 个,具体数量取决于画板的大小。您可以在最初创建文档时指定文档的画板数,并且在处理文档的过程中,可以随时添加和删除画板。您可以创建大小不同的画板

  • 在Sketch中,可以通过画板(Artboard)在无限大的画布(Canvas)上设置一个固定框架,但画板并非必须,是否创建画板完全取决于你。在文档中设置了画板后,画板外面的区域将会变淡,因此你可以清楚地看见哪些元素落在画布里,哪些没有。 如果正在做一个网站设计,你可能希望考虑不同尺寸的屏幕,并且将每种屏幕尺寸转换为相应的画板。如果你在制作图标,你可能希望以几种默认的图标尺寸来作为边界,那就可以为

  • 利用UIVIew的drawrect方法,创建画板,能定义线条粗细与线条颜色,支持重做(redo)和撤销(undo)操作,并且支持将绘画保存到本地。 [Code4App.com]

  • 利用cocos2d来实现一个画板功能,可以画线、画方形、画圆(包括椭圆),也可以用虚线进行绘制,还可以选择颜色、保存图片等等。 [Code4App.com]