调整大小时无法保持大小的居中游戏片段

时间:2018-09-05 20:53:05

标签: java swing

我有一个棋盘游戏(认为是专卖),可以在单个图块上放置多个游戏块。我在绿色背景上绘制了4个圆圈,但是圆圈没有居中,当我调整它们的大小时,圆圈会在整个位置上移动,而不是停留在图块上。

CirclePanel:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class CirclePanel extends JPanel {
    public static final Dimension SIZE = new Dimension(35, 35);

    public CirclePanel() {
    }

    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(Color.RED);
        g.fillOval(0, 0, 35, 35);
        System.out.println(getSize());
    }

    @Override
    public Dimension getPreferredSize() {
        return SIZE;
    }
}

GraphicsTile:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;

@SuppressWarnings("serial")
public class GraphicsTile extends JPanel {
    public static final Dimension SIZE = new Dimension(140, 140);
    public static final GridLayout MGR = new GridLayout(2, 2);

    public GraphicsTile() {
        super();
        setLayout(MGR);

        add(new CirclePanel());
        add(new CirclePanel());
        add(new CirclePanel());
        add(new CirclePanel());

    }

    @Override
    public Dimension getPreferredSize() {
        return SIZE;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.GREEN);
        g.fillRect(0, 0, 140, 140);
    }
}

GraphicsRunner:

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;

public class GraphicsRunner {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(new GridLayout(4, 0, 5, 5));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(1280, 720);
        frame.setPreferredSize(new Dimension(140, 140));
        frame.add(new GraphicsTile());
        frame.add(new GraphicsTile());
        frame.setVisible(true);
    }
}

2 个答案:

答案 0 :(得分:3)

再一次,不要玩大号了。所有Swing组件都应确定自己的首选大小。这包括面板和框架。

面板将根据添加到面板中的组件确定其大小。

框架将根据添加到框架的面板确定其大小。添加面板后,您可以使用pack()方法。

然后所有组件将以其首选大小显示。然后,您可以使用以下方法将框架固定为固定大小:

frame.setResizable( false );

但是,如果您不执行上述操作,则需要确定调整框架大小后会发生什么。然后,您需要更加注意所使用的布局管理器。

对于GridLayout,所有组件的大小都会进行调整以填充所有可用空间。通过将GraphicsTile`中的绘画代码更改为:

,可以轻松验证这一点。
//g.fillRect(0, 0, 140, 140);
g.fillRect(0, 0, getWidth(), getHeight());

这是更好的绘画技术。您不应该对值进行硬编码。在适当的时候使用组件的属性来指定参数。

如果执行此操作,您会看到磁贴会扩大以填充该区域,并且CirclePanel位于GraphicsTile的开头(同样是因为您对位置进行了硬编码)。

为防止GraphicsTile扩大尺寸,您需要将其包装在另一个面板中,该面板应遵守添加到其中的组件的首选大小。

一种简单的方法是将GridBagLayout与默认GridBagConstraints一起使用。现在,添加到其中的所有组件都将位于可用空间的中心。

所以您对main()方法的重组看起来像:

JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());

JPanel tilePanel = new JPanel( new GridLayout(0, 1, 5, 5) );
tilePanel.add(new GraphicsTile());
tilePanel.add(new GraphicsTile());

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tilePanel, new GridBagConstraints());
frame.pack();
frame.setVisible(true);

答案 1 :(得分:0)

这是因为GridLayout会使用所有可用空间自动扩展内容。

您可以通过将GraphicsTiles用另一个JPanel(默认情况下使用FlowLayout)包装来避免这种情况。这样,GridLayout将被迫保留在包装中。

例如,在GraphicsRunner中,您可以使用panel作为包装器:

JPanel panel = new JPanel();
panel.add(new GraphicsTile());
frame.add(panel);

panel = new JPanel();
panel.add(new GraphicsTile());
frame.add(panel);

但是您可能想研究其他布局(甚至根本不使用布局)是否更适合您的需求。

这里有一个类似的问题可能会有所帮助:How to set the component size with GridLayout? Is there a better way?