让Java显示超过1个.add()

3

我已经开始学习基础Java并且想要重写一个游戏地图生成器,这个生成器之前是用PHP写的。其中一部分已经正常工作(这只是开始),但是每当我想要展示两个东西(使用.add())时,它只会展示其中一个。以下是我的代码:

public static void main(String[] args) {
    JFrame m1 = new JFrame();
    Container con = m1.getContentPane();
    Color c = new Color(16, 174, 0);
    con.setBackground(c);
    m1.setSize(mapWidth, mapHeight);
    m1.setTitle("ThomasMosey's Map Generator"); // Window Title
    m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    m1.add(new User());
    m1.add(new Grid());
    m1.setVisible(true);
}

这只是代码的一部分,我想知道在 .add 部分是否有任何错误。

提前感谢您。


以下是完整代码;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class Map extends JFrame {
    public static int mapWidth = 576; // The Map's Width
    public static int mapHeight = 598; // The Map's Height
    public static int userX = 1;
    public static int userY = 1;
    private static final long serialVersionUID = 1L;
    public static void main(String[] args) {
        JFrame m1 = new JFrame();
        Container con = m1.getContentPane();
        Color c = new Color(16, 174, 0);
        con.setBackground(c);
        m1.setSize(mapWidth, mapHeight);
        m1.setTitle("ThomasMosey's Map Generator"); // Window Title
        m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        con.add(new User(), BorderLayout.NORTH);
        con.add(new Grid(), BorderLayout.CENTER);
        m1.setVisible(true);
    }
}
// The Grid system
class Grid extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g2.setColor(gridColor);
        int i;
        int i2;
        for(i = 50; i <= Map.mapWidth; i += 51) {
            g2.drawLine(0, i, Map.mapWidth, i);
        }
        for(i2 = 50; i2 <= Map.mapHeight; i2 += 51) {
            g2.drawLine(i2, 0, i2, Map.mapHeight);
        }
    }
}
// Drawing the Grid but lower down to give a significant difference to check whether or not it's actually drawing on the JFrame
class User extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paint(Graphics g2) {
        Graphics2D g22 = (Graphics2D) g2;
        g22.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g22.setColor(gridColor);
        int i22;
        for(i22 = 50; i22 <= 6000; i22 += 53) {
            g22.drawLine(0, i22, Map.mapWidth, i22+1);
        }
    }
}

"这只是代码的一部分..." 为了更快地获得帮助,请发布一个SSCCE。如果您这样做了,我会在发布答案之前进行测试。 - Andrew Thompson
我刚刚发布了我的完整代码。它不是一个非常大的文件。 - oyed
那是一个经典的 SSCCE。请查看我的编辑获取更多提示。 - Andrew Thompson
3个回答

5
  1. 内容面板的默认布局是BorderLayout
  2. 添加一个没有限制条件的组件到边框布局中,它会被放置在CENTER位置。
  3. 每个边框布局的部分只能出现一个组件。

因此,请尝试使用以下方法...

m1.add(new User(), BorderLayout.NORTH);
m1.add(new Grid(), BorderLayout.CENTER);

问题的一部分在于自定义组件的默认首选大小为0x0。尝试使用以下变体。
import java.awt.*;
import javax.swing.*;

public class Map extends JFrame {
    public static int mapWidth = 576; // The Map's Width
    public static int mapHeight = 598; // The Map's Height
    public static int userX = 1;
    public static int userY = 1;
    private static final long serialVersionUID = 1L;
    public static void main(String[] args) {
        JFrame m1 = new JFrame();
        Container con = m1.getContentPane();
        Color c = new Color(16, 174, 0);
        con.setBackground(c);
        // bad form - pack() instead
        //m1.setSize(mapWidth, mapHeight);
        m1.setTitle("ThomasMosey's Map Generator"); // Window Title
        m1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        User user = new User();
        user.setPreferredSize(new Dimension(300,300));
        con.add(user, BorderLayout.NORTH);
        Grid grid = new Grid();
        grid.setPreferredSize(new Dimension(600,600));
        con.add(grid, BorderLayout.CENTER);
        m1.pack();
        m1.setVisible(true);
    }
}
// The Grid system
class Grid extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g2.setColor(gridColor);
        int i;
        int i2;
        for(i = 50; i <= Map.mapWidth; i += 51) {
            g2.drawLine(0, i, Map.mapWidth, i);
        }
        for(i2 = 50; i2 <= Map.mapHeight; i2 += 51) {
            g2.drawLine(i2, 0, i2, Map.mapHeight);
        }
    }
}
// Drawing the Grid but lower down to give a significant difference to check whether or not it's actually drawing on the JFrame
class User extends JComponent {
    private static final long serialVersionUID = 1L;
    public void paintComponent(Graphics g2) {
        Graphics2D g22 = (Graphics2D) g2;
        g22.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Color gridColor = new Color(0, 84, 12);
        g22.setColor(gridColor);
        int i22;
        for(i22 = 50; i22 <= 6000; i22 += 53) {
            g22.drawLine(0, i22, Map.mapWidth, i22+1);
        }
    }
}

添加BorderLayout.CENTER和BorderLayout.PAGE_START并没有改变它。编辑:你的第二个修复方法没有起作用。 - oyed
它可以工作,但我想让它们叠在一起。有什么方法可以做到这一点吗? - oyed
什么,GridUser?在这里,用户确实出现在 Grid 的“顶部”。你的意思是它们应该分层吗?用户是透明的,你可以看到它后面的网格吗? - Andrew Thompson
是的 - 如果可能的话,那就是我想要的。抱歉没有给足够的细节。 - oyed
你可以尝试使用JLayeredPane。我暂时不会举例说明两个原因:1)我认为这是错误的方法,应该使用单个自定义组件来绘制用户和网格。2)使用JLayeredPane很麻烦,我很难理解它。 :) - Andrew Thompson
1
哈哈,谢谢你的帮助!我会考虑把它们都合并成一个类。再次感谢。 - oyed

2

当前的JFrame布局是BorderLayout,而你正在将这两个组件添加到中心位置。尝试更改布局。

Container con = m1.getContentPane();
con.setLayout(new FlowLayout());

或者
m1.add(new User(),BorderLayout.NORTH);
m1.add(new Grid(),BorderLayout.CENTER);

编辑:您需要覆盖User类的setPreferredSize()方法。

class User extends JComponent {
  public java.awt.Dimension getPreferredSize() { 
    return new java.awt.Dimension(100,100);
  }
}

感谢您恢复您的答案。即使在了解首选大小的建议之前,我也准备好进行投票支持。(尽管我不同意最好重写方法,但这更多是一个设计问题。) - Andrew Thompson

0

据我所知,默认情况下,内容面板(content pane)只接受单个子元素。如果您想要有多个子元素,您需要设置和配置一些布局。


一个 JFrame 的内容面板可以接受 5 个组件而不改变布局。 - Andrew Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接