我打算编写一个小版本的“Pong”。但我已经遇到了JPanels
的问题。 Shields
的大小从100变为非常奇怪到10。并且没有方法可以改变它的大小!
盾牌也跳到了JPanel
的中上部。他们不希望这样做。看到帖子的两个截图。 (Puu.sh)
很抱歉,如果我错过了一些明显的东西,但就像我说的那样,我正在训练。
主要有psvm()
public class Main {
public static void main(String[] args) {
new Field();
}
}
Field(包含游戏的框架)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class Field extends JFrame {
private Room room = new Room();
public Field() {
this.setSize((int) (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 1.5), (int) (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 1.5));
this.setLayout(null);
this.setLocation((int) ((Toolkit.getDefaultToolkit().getScreenSize().getWidth() - (Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 1.5)) / 2), (int) ((Toolkit.getDefaultToolkit().getScreenSize().getHeight() - (Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 1.5)) / 2));
this.getContentPane().setBackground(Color.GRAY);
this.setResizable(true);
this.setEnabled(true);
this.setMinimumSize(new Dimension(1000, 455));
if (getHeight() < 455) {
this.setSize(getWidth(), 455);
} else if (getWidth() < 1000) {
this.setSize(1000, getHeight());
}
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(room);
this.setVisible(true);
addMouseListener(this);
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent evt) {
room.updateLocation(getSize());
}
});
}
}
间
import javax.swing.*;
import java.awt.*;
public class Room extends JPanel {
private Shield shieldL = new Shield(0); // LEFT side
private Shield shieldR = new Shield(1); // RIGHT side
public Room() {
this.setBackground(new Color(122, 197, 205));
this.add(shieldL);
this.add(shieldR);
}
public void updateLocation(Dimension d) {
this.setSize((int) d.getWidth(), (int) (d.getHeight() - (d.getHeight() / 5)));
this.setLocation(0, (int) (d.getHeight() / 10));
shieldL.updateLocation(getSize());
shieldR.updateLocation(getSize());
this.setVisible(true);
}
}
屏蔽
import javax.swing.*;
import java.awt.*;
public class Shield extends JPanel {
private int side = 0;
public Shield(int s) { //0 = Left | 1 = Right
side = s;
this.setSize(10, 100);
this.setBackground(Color.white);
}
public void updateLocation(Dimension d) { //Bug found here
System.out.println(getSize()); //Bug seems not to be created here?
int xPos;
if (side == 0) {
xPos = (int) (d.getWidth() / 8);
} else {
xPos = (int) (d.getWidth() / 8 * 7 - this.getWidth() / 2);
}
this.setLocation(xPos, (int) (d.getHeight() / 2 - (getHeight() / 2)));
this.setVisible(true);
}
}
他们最终是这样的:在randome framesize changings中切换位置。
http://puu.sh/ceyE0/ef15ee1748.png
http://puu.sh/ceyFN/122174db48.png
谢谢! 朱利安:)
答案 0 :(得分:0)
在Shield
中,更改行
setSize(10, 100);
到
setPreferredSize(new Dimension(10, 100));
不要使用setSize
方法,它们在内部调用。
修改强>
只尝试这两个类:
public class Field extends JFrame {
private Room room = new Room();
public Field() {
//Mock panel
JPanel filler = new JPanel();
filler.setOpaque(false);
getContentPane().setBackground(Color.GRAY);
getContentPane().add(filler, BorderLayout.PAGE_START);
getContentPane().add(room);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setMinimumSize(new Dimension(1000, 455));
setLocationRelativeTo(null);
pack();
room.init();
setVisible(true);
}
}
public class Room extends JPanel {
private static int leftWidth = 100;
private static int leftHeight = 100;
private static int leftX;
private static int leftY;
private static int rightWidth = 100;
private static int rightHeight = 100;
private static int rightX;
private static int rightY;
public Room() {
setBackground(new Color(122, 197, 205));
}
void init() {
leftX = getWidth() / 8;
leftY = getHeight() / 2 - leftHeight / 2;
rightX = getWidth() * 7 / 8;
rightY = getHeight() / 2 - rightHeight / 2;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
g2d.fillRect(leftX, leftY, leftWidth, leftHeight);
g2d.fillRect(rightX, rightY, rightWidth, rightHeight);
}
}
答案 1 :(得分:0)
您的问题是您不了解布局管理器以及它们如何处理或使用setSize,setPreferredSize,setMinimumSize和setMaximumSize方法。
对于面板类,setSize不起作用,因为在创建JPanel时,它使用FlowLayout作为默认布局管理器,布局管理器忽略setSize方法指定的大小。您必须以某种组合方式使用其他组合(至少一种)。您可以使用setSize的唯一方法是通过调用setLayout(null)为默认情况下不分配布局管理器的组件。这称为绝对定位。这是您必须指定每个组件的位置和大小的地方。
搜索Java Swing教程并搜索&#34;如何使用布局管理器。&#34;如果您使用的是Swing,那么您理解这个概念是非常重要的,因为不同的布局管理器遵循不同的大小和定位规则。例如,Flow Layout和Grid Layout的表现非常不同。
当然,绝对定位是一种痛苦,但它是一种方法,可以绝对控制Swing组件的大小和位置。但是理解布局管理器并正确使用它们可以为您节省大量时间来创建GUI。
*****更新信息***** 调整框架大小的问题是由于您的面板正在使用FlowLayout。此布局管理器允许重新排列面板中的组件。有几种方法可以解决这个问题。一种是使用布局管理器,在调整组件大小时保留组件的宽高比。例如,GridLayout&#34;分解&#34;一个组件成网格。如果你想到一个棋盘,它是一个8x8网格。如果您将面板制作成完美的正方形,那么所有网格都将是相同大小的正方形。调整面板大小时,将保留面板的纵横比(不一定是内部组件)。另一种方法,也许是你学习如何正确使用布局管理器的最佳选择,是防止框架的大小调整。