所以我已经编写Java几个月了,我一直在用JOptionPane
我的游戏中显示文本和变量.我想像普通游戏一样升级到单个窗口,但我只想关注屏幕上的简单按钮和文本.我曾试图学习JFrame
和ActionListsner
,但我没能completley看着办吧.JFrame
我真的很困惑.
我的问题是:是否有一个更简单的方法JFrame
就是只有一个窗口,我可以拥有简单的文本,按钮,TextFields
没有打开一堆窗口的麻烦JOptionPane
,使得ActionListener
带有JFrame
或不得不进入GUI的垃圾负载?如果没有,我在哪里可以找到有关如何制作游戏的帮助JFrame
?
你应该使用一个JFrame
.相信我,他们并不难以使用.使用a JFrame
,您可以创建多个面板并使用它们在它们之间切换CardLayout
.
既然你说你不确定它是如何JFrame
工作的,我在这篇文章的最后给出了一个简短的介绍.但首先,让我们首先谈谈如何解决您的问题.
通过CardLayout切换面板
当你想要完全切换在窗口中查看的内容时,你会想要一个完全不同的面板用于特定目的(例如,一个用于主菜单,一个用于游戏).CardLayout
是为此而创建的.
您指定"甲板"面板.此面板将保存您想要切换的所有其他面板(卡片):
CardLayout layout = new CardLayout();
JPanel deck = new JPanel();
deck.setLayout(layout);
Run Code Online (Sandbox Code Playgroud)
您需要维护对布局的引用(通过变量),以便您可以在面板之间切换.
现在我们有了一个"甲板"面板,我们需要添加一些卡片.我们通过创建更多JPanels并在将它添加到框架时指定名称(约束)来实现此目的:
JPanel firstCard = new JPanel();
JPanel secondCard = new JPanel();
deck.add(firstCard, "first");
deck.add(secondCard, "second");
Run Code Online (Sandbox Code Playgroud)
添加到卡组的第一张卡片将始终是第一张显示的卡片.
添加完所有卡后,您可以通过呼叫切换它们layout.show(deck, "second");
.这是您使用CardLayout
如何管理容器中的多个面板的方法.
创建监听器
没有更简单的方法来管理它.它只会变得更难(绑定 - 我强烈建议你调查它们).对于听众来说,有两个步骤:
如果您使用lambda"动态"创建了侦听器,则可以为1:
JButton button = new JButton();
//Java 8+
button.addActionListener(event -> {
//whenever you click the button, code in here triggers
});
Run Code Online (Sandbox Code Playgroud)
对于那些不使用Java 8的用户,您需要使用匿名类:
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//whenever you click the button, code in here triggers
}
});
Run Code Online (Sandbox Code Playgroud)
只有一些组件支持ActionListener
.任何伸出AbstractButton
,像JMenuItem
,JButton
,JRadioButton
,多会支持ActionListener
秒.JTextField
也支持它,即使它不是AbstractButton
.KeyListener
但是,每个组件都支持,它们也可用于侦听来自用户的输入事件.
如果您对此有任何疑问,请告诉我,我很乐意回答.
使用Swing组件
的JFrame
你初始化了一个JFrame
:
JFrame frame = new JFrame();
Run Code Online (Sandbox Code Playgroud)
然后,您需要设置defaultCloseOperation
,以确定窗口关闭时会发生什么:frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
有不同的选项,但EXIT_ON_CLOSE
会在关闭窗口后终止您的程序.如果您没有设置defaultCloseOperation
,那么您的窗口将关闭,但您的程序仍将运行.BIG NO NO.如果您不希望在关闭框架时退出整个程序,请使用DISPOSE_ON_CLOSE
.
关闭操作后,您可能想要设置大小.这是不好的做法.您的框架应根据其内部的大小来确定尺寸.为此,您将组件添加到框架中,然后调用pack()
:
JButton button = new JButton("Button");
frame.add(button);
//add other components
frame.pack();
Run Code Online (Sandbox Code Playgroud)
这将确保您的框架尺寸适合其内部.您应该始终从内到外设计GUI,以确保您始终有足够的空间来满足您的需求.
集装箱
JFrame
是一个Container
.容器只是容纳其他组件的组件.所有容器都应具有LayoutManager
管理组件布局的方式,如果需要,还可以管理大小.JFrame
虽然不是唯一的容器.JPanel
实际上是一个意味着要添加到另一个容器(或窗口)的容器.您可以向a添加内容JPanel
,然后将该面板添加到另一个容器中.这就是你整洁有序的方式.容器非常简单,所以没什么可说的.
内容窗格
当你创建一个时JFrame
,它会出现一个叫做的东西contentPane
.它JPanel
嵌套在JFrame中.当你这样做时frame.add(button)
,你会发现add
实际上是指contentPane:
//in Container class
public Component add(Component comp) {
addImpl(comp, null, -1); //where it's added
return comp;
}
//In JFrame class (overriding)
protected void addImpl(Component comp, Object constraints, int index) {
if(isRootPaneCheckingEnabled()) {
getContentPane().add(comp, constraints, index); //adds to content pane instead
} else {
super.addImpl(comp, constraints, index); //if root panes were not supported, which they currently are
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用从框架中获取contentPane
Container pane = frame.getContentPane();
Run Code Online (Sandbox Code Playgroud)
contentPane的Container
形式是为了确保一个强大的API(如果不再使用JPanels,我们就不必担心更改getContentPane的方法类型).虽然,因为它是一个JPanel,你可以把它转换回它的原始形式:
JPanel pane = (JPanel) frame.getContentPane();
Run Code Online (Sandbox Code Playgroud)
虽然通常不需要它.使用它作为一个Container
往往工作得很好.
布局
JFrame
默认情况下,使用BorderLayout
,但您可以通过调用setLayout
容器的方法来更改它:
FlowLayout layout = new FlowLayout();
frame.setLayout(layout);
Run Code Online (Sandbox Code Playgroud)
在跳转到布局之前,我想提一下JPanel
使用FlowLayout
默认值,除了框架的默认contentPane,你也可以通过这样做来改变frame.setContentPane(...)
.contentPane BorderLayout
用作默认值.
现在,让我们谈谈一对,从JFrame
默认开始:BorderLayout
.
一些布局需要所谓的约束,这些约束告诉布局如何处理正在添加的特定组件.将组件添加到容器时指定这些约束:
frame.add(button, BorderLayout.SOUTH);
Run Code Online (Sandbox Code Playgroud)
BorderLayout
很简单.您有5个选项:NORTH,SOUTH,EAST,WEST或CENTER.(还有其他值,如PAGE_START,可以互换.最好只使用更简单的表格)
所有约束BorderLayout
都是静态字段变量,您调用的类似于我的方式.BorderLayout
实际上是一个易于使用的布局,看看它没有多少.即使它的简单性限制了你可以做的事情(你只能把它放在像NORTH这样的特定位置),你通常会结合布局来获得你想要的结果.与其他布局结合使用时,此布局非常强大.
FlowLayout
是非常直接的,以及其他布局.其中一个不那么直截了当GridBagLayout
,可以是一个非常灵活的布局.它也可能相当复杂,因为文档甚至指出.
使用时GridBagLayout
,需要创建约束对象:GridBagConstraints
.要使用GridBagLayout
,您可以使用约束对象设置约束,然后将组件和约束添加到容器中:
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JButton button = new JButton("yoyoyo");
frame.add(button, gbc);
Run Code Online (Sandbox Code Playgroud)
即使我们不调整约束,我们仍然必须在向容器添加组件时指定它.
让我们说我们有4个按钮,我们想把它们并排放置.您可以调整约束gridx
和gridy
值:
JButton button = new JButton("1");
JButton button2 = new JButton("2");
JButton button3 = new JButton("3");
JButton button4 = new JButton("4");
frame.add(button, gbc);
gbc.gridx = 1; //or gridx += 1, or gridx = 1. gridx starts at 0
frame.add(button2, gbc);
gbc.gridx = 0; //must reset the value back to normal
gbc.gridy = 1;
frame.add(button3, gbc);
gbc.gridx = 1;
//since gridy already == 1, no need to change it
frame.add(button4, gbc);
Run Code Online (Sandbox Code Playgroud)
我们可以使用相同的约束对象,只要我们在需要时重置值.
GridBagLayout
除非另有说明,否则开始居中,并从中心开始工作.您也不能跳过网格空间.此外,正如您将注意到的,所有按钮都将触摸.如果您想在每个组件之间留出一点空间,可以设置insets
约束:
int top = 5, left = 5, bottom = 1, right = 1;
gbc.insets.set(top, left, bottom, right);
Run Code Online (Sandbox Code Playgroud)
这个布局还有很多,遗憾的是我觉得这不是解释它的最佳位置,看看它是如何记录的(我甚至添加了链接).
还有很多其他布局.尽可能多地熟悉,然后找到有助于满足您需求的那些.定位应始终依赖于LayoutManager
所使用的.至于尺寸,这有点取决于你正在使用的布局.
归档时间: |
|
查看次数: |
186 次 |
最近记录: |