【问题标题】:Layering many JPanels and adding them on the fly将许多 JPanel 分层并动态添加它们
【发布时间】:2009-07-11 23:14:44
【问题描述】:

我正在开发一款基于主题医院的模拟游戏,这是一款相当古老的游戏。 我在底层工作方面取得了很大进展,但是现在我开始讨论 GUI 元素,这是我以前没有做过的很多事情。我对java还是比较陌生。 我试图创建的效果就像这里显示的那样......

http://www.tubechop.com/watch/18438

单击一个按钮,打开一个带有选项卡的面板以从不同的选项中进行选择,然后单击一个按钮来构建一个房间。我相信对于“标签”我可以使用卡片布局?对于房间的实际建造,我几乎是分类的。我现在遇到的主要问题是让面板在单击按钮时打开。

目前,我在顶部有 1 个 JFrame 和 2 个 JPanel,主游戏面板和带有几个按钮的控制面板。

谁能告诉我一些简单的例子来说明我会如何做这样的事情?我知道它可能真的很简单,而且我敢打赌,你们中的一些人甚至可以将代码写下来,但我是 Java 新手,到目前为止,我学到的更多是关于编程的逻辑元素,而不是如何构建游戏中所需的更复杂的多层 GUI。

我知道这是一个雄心勃勃的项目,但我已经走了很长一段路,甚至使用 A* 实现了自定义路径查找,我很高兴(感谢 StackOverflow 的各位!)

提前感谢您的帮助。

【问题讨论】:

  • 我没办法,但祝你好运!那是一场多么棒的比赛。这会是商业版本吗?
  • 谢谢。没办法我的朋友,免费软件一路开源。我希望它可以成为一个足够大的项目,像 OTTD 一样受到关注。虽然 OTTD 给我带来了许多小时的乐趣,但我玩的第一个模拟游戏是主题医院。我想与人们分享玩 TH 的回忆,带有现代风格和令人兴奋的新玩法! :)
  • 您有为此运行的站点吗?我敢说我可能有兴趣做出贡献。
  • 目前我没有设置网站。我仍在决定名称,但一旦完成,我将发布我的进度。我知道有一些项目像这样消失或停止工作。我计划让这件事保持安静,直到我有一些合理的东西可以展示。图形方面,它并不令人印象深刻,但由于这只是我的第二场比赛,我对我的缓慢进展感到满意:P 如果你想谈论这个项目,请 PM 我,我们可以通过某种形式的 IM 或通过电子邮件聊天.
  • 这里没有 PM 系统...如果您访问我的网站 (appaholic.co.uk) 并向下滚动到底部,您可以在我在线时与我聊天(英国时间),我们可以交换 IM 地址。

标签: java jframe jpanel layer


【解决方案1】:

JDialogs 可以工作,但它们会在您的游戏窗口上弹出新的顶级窗口。您可以将主游戏显示和控制面板实现为 JDesktopPane(扩展 JLayeredPane)的背景,并且可以制作弹出窗口 JInternalFrames。

人为的(但有效的)示例:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentAdapter;
import java.awt.event.ActionListener;
import java.text.NumberFormat;

public class DesktopTest extends JFrame {

private JDesktopPane desktop;
private JPanel background;
private JInternalFrame firstFrame;
private JInternalFrame secondFrame;

public DesktopTest() {
    super("DesktopTest");

    desktop = new JDesktopPane();
    setContentPane(desktop);

    background = new JPanel(new BorderLayout());
    JToolBar toolbar = new JToolBar();
    toolbar.add(new AbstractAction("1") {

        public void actionPerformed(ActionEvent actionEvent) {
            firstFrame.setVisible(true);
        }
    });

    toolbar.add(new AbstractAction("2") {

        public void actionPerformed(ActionEvent actionEvent) {
            secondFrame.setVisible(true);
        }
    });
    AddPanel addPanel = new AddPanel();
    background.add(addPanel, BorderLayout.CENTER);
    background.add(toolbar, BorderLayout.SOUTH);
    addComponentListener(new ComponentAdapter() {

        public void componentResized(ComponentEvent componentEvent) {
            background.setSize(desktop.getSize());
            background.revalidate();
            background.repaint();
        }

        public void componentShown(ComponentEvent componentEvent) {
            background.setSize(desktop.getSize());
            background.revalidate();
            background.repaint();
        }
    });
    desktop.add(background);

    firstFrame = new TermFrame("First Term", "Update First Term: ", addPanel) {

        protected int getValue() {
            return addPanel.getFirst();
        }

        protected void update(int value) {
            addPanel.setFirst(value);
        }
    };
    firstFrame.pack();
    firstFrame.setBounds(10, 10, 200, 150);
    desktop.add(firstFrame);

    secondFrame = new TermFrame("Second Term", "Update Second Term: ", addPanel){

        protected int getValue() {
            return addPanel.getSecond();
        }

        protected void update(int value) {
            addPanel.setSecond(value);
        }
    };
    secondFrame.pack();
    secondFrame.setBounds(200, 200, 200, 150);
    desktop.add(secondFrame);

}

public static void main(String[] args) {
    JFrame f = new DesktopTest();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setSize(400, 400);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
}

static class AddPanel extends JPanel {
    private JLabel first;
    private JLabel second;
    private JLabel result;

    public AddPanel() {
        first = new JLabel("0");
        second = new JLabel("0");
        result = new JLabel("0");

        Box vertical = Box.createVerticalBox();
        vertical.add(Box.createVerticalGlue());
        Box horizontal = Box.createHorizontalBox();
        horizontal.add(Box.createHorizontalGlue());
        horizontal.add(first);
        horizontal.add(new JLabel("+"));
        horizontal.add(second);
        horizontal.add(new JLabel("="));
        horizontal.add(result);
        horizontal.add(Box.createHorizontalGlue());
        vertical.add(horizontal);
        vertical.add(Box.createVerticalGlue());

        setLayout(new BorderLayout());
        add(vertical, BorderLayout.CENTER);
    }

    public void setFirst(int i) {
        first.setText(Integer.toString(i));
        updateResult();
    }

    public int getFirst() {
        return Integer.parseInt(first.getText());
    }

    public void setSecond(int j) {
        second.setText(Integer.toString(j));
        updateResult();
    }

    public int getSecond() {
        return Integer.parseInt(second.getText());
    }

    private void updateResult() {
        int i = Integer.parseInt(first.getText());
        int j = Integer.parseInt(second.getText());
        result.setText(Integer.toString(i + j));
        revalidate();
    }
}

static abstract class TermFrame extends JInternalFrame {

    protected AddPanel addPanel;
    private JFormattedTextField termField;

    public TermFrame(String title, String message, AddPanel addPanel) {
        super(title, true, true, true);
        this.addPanel = addPanel;
        NumberFormat format = NumberFormat.getNumberInstance();
        format.setMaximumFractionDigits(0);
        termField = new JFormattedTextField(format);
        termField.setColumns(3);
        termField.setValue(getValue());

        JPanel content = new JPanel(new FlowLayout());
        content.add(new JLabel(message));
        content.add(termField);
        JButton apply = new JButton("apply");
        apply.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent actionEvent) {
                Integer value = Integer.parseInt(termField.getText());
                update(value);
            }
        });
        content.add(apply);
        setContentPane(content);

        setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
    }

    protected abstract int getValue();

    protected abstract void update(int value);


}
}

【讨论】:

  • 这在我看来正是我正在寻找的东西。谢谢。有人有这方面的cmet吗?这种做法是好是坏,还是取决于个人喜好?
  • 嗨内特。我在将它实施到我的项目中时遇到了一些问题。我可能犯了一些非常愚蠢的错误,但现在已经调整了大约 2-3 个小时,所以在我再次搞砸之前,我想是时候问一下了……这是我认为相关代码位的链接。 ..snipt.org/kpJ提前致谢
  • 我的错,我定义了 mainPane 两次。进步! :) 现在有一些其他有趣的问题,但希望我能得到它!
  • 抱歉 - 之前没有启用,但很高兴知道您可以使用它。 :)
  • 谢谢,好的。是的,它几乎可以工作,只是当它使内部框架可见时,似乎掩盖了大多数其他东西......我在这里制作了一个快速视频,向您展示我的意思。 is.gd/1wVIK 再次感谢您的帮助! :)
【解决方案2】:

我现在的主要问题是 让面板在 点击一个按钮。

您不会打开另一个面板。您可能会使用包含另一个面板的 JDialog。然后您可以使用 CardLayout 或者您可以在对话框中使用 JTabbedPane。设计选择由您决定。

我建议您首先阅读Swing tutorial 以获取所有组件的示例。我真的不能就程序的图形提供任何建议。为此,您需要开始提出具体问题。但是使用面板和组件构建对话框是直截了当的。

【讨论】:

    【解决方案3】:

    按钮处理非常简单。您需要有一个类实现ActionListener 接口,并且需要使用您的按钮注册它。你可以看到一些非常清晰的例子here

    对于您想要调出的面板,看起来您正在寻找的内容可以在顶级 Swing 容器中内置的 Root Pane 框架中找到。 Here is a tutorial.

    根窗格框架包括玻璃窗格,这是一个清晰的窗格,位于顶级组件的 z 顺序堆栈的顶部。您还拥有分层窗格,它可能更适合您的需求。有一个tutorial for that as well

    【讨论】:

      猜你喜欢
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多