分层许多JPanel并即时添加它们

时间:2009-07-11 23:14:45

标签: java jframe jpanel layer

我正在开发一款基于主题医院的SIM游戏,这是一款相当古老的游戏。 我在底层工作方面取得了很多进展,但是现在我要进入GUI元素,我以前没有做过很多。我还是java的新手。 我试图创造的效果就像这里所示......

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

单击按钮,打开一个带有选项卡的面板,以从不同的选择中进行选择,然后单击按钮以构建房间。我相信“标签”我可以使用卡片布局?对于房间的实际建设,我几乎排序。我现在面临的主要问题是,只需点击一下按钮即可打开面板。

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

有谁能告诉我一些如何做这样事情的简单例子?我知道它可能非常简单,我敢打赌你们中的一些人甚至可以把代码写到头脑中,但我是java的新手,并且到目前为止已经有更多关于编程的逻辑元素的教学而不是如何构建游戏中需要的更复杂的多层GUI。

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

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

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

Contrived(但工作)示例:

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);


}
}

答案 1 :(得分:0)

  

我现在面临的主要问题是   让小组打开   点击按钮。

您没有打开另一个面板。您可能会使用包含另一个面板的JDialog。然后,您可以使用CardLayout,也可以在对话框中使用JTabbedPane。设计选择取决于您。

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

答案 2 :(得分:0)

按钮处理非常简单。您需要有一个类实现ActionListener接口,并且需要使用您的按钮进行注册。您可以看到一些非常明确的示例here

对于您想要显示的面板,您可以在顶层Swing容器中内置的Root Pane框架中找到您要查找的内容。 Here is a tutorial

Root Pane框架包括Glass Pane,它是一个透明窗格,位于顶层组件的z-order堆栈的顶部。您还可以使用Layered Pane,它可能更适合您的需求。有tutorial for that as well