JPanel的位置和尺寸变得怪异

时间:2014-10-16 15:17:32

标签: java location jpanel size pong

我打算编写一个小版本的“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

谢谢! 朱利安:)

2 个答案:

答案 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网格。如果您将面板制作成完美的正方形,那么所有网格都将是相同大小的正方形。调整面板大小时,将保留面板的纵横比(不一定是内部组件)。另一种方法,也许是你学习如何正确使用布局管理器的最佳选择,是防止框架的大小调整。