Java 背景前未打印多个JPanel

Java 背景前未打印多个JPanel,java,swing,jframe,Java,Swing,Jframe,我想创建一个日历,根据它所基于的月份自动创建自己。首先,我创建了一个可以在任何月份使用的背景,它的尺寸是每天700x500 700/7,每个月500/5,但从周一开始的28天2月有5行周。我是这样说的: public class Graph { private final int sizeX = 700; private final int sizeY = 500; private Calendar calendar; public Graph(Calend

我想创建一个日历,根据它所基于的月份自动创建自己。首先,我创建了一个可以在任何月份使用的背景,它的尺寸是每天700x500 700/7,每个月500/5,但从周一开始的28天2月有5行周。我是这样说的:

public class Graph {

    private final int sizeX = 700;
    private final int sizeY = 500;
    private Calendar calendar;


    public Graph(Calendar calendar) {
        this.calendar = calendar;
        JFrame frame = new JFrame();
        graph(frame);
    }

    public void graph(JFrame frame) {
        buildBackground(frame);
    }

    private void buildBackground(JFrame frame) {
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(sizeX, sizeY);
        JPanel panel = new Background(sizeX, sizeY);
        frame.add(panel);
        frame.validate();
        frame.repaint();
    }
}

public class Background extends JPanel {

    private int sizeX;
    private int sizeY;

    public Background(int sizeX, int sizeY) {
        this.sizeX = sizeX;
        this.sizeY = sizeY;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.DARK_GRAY);
        g.fillRect(0, 0, sizeX, sizeY);
    }
}
如果工作正常,则会正确创建深灰色背景。当我试图创建表示日期的小矩形时,问题就出现了;我设计了一个类,我想在特定坐标上表示这些矩形:

public class DayRectangle extends JPanel {

    private int posX;
    private int posY;
    private int day;

    public DayRectangle(int posX, int posY, int day) {
        this.posX = posX;
        this.posY = posY;
        this.day = day;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(posX, posY, 60, 60);
    }

    public Dimension getPreferredSize() {
        return new Dimension (60, 60);
    }

    @Override
    public String toString() {
        return String.format("(%d,%d):%d", posX, posY, day);
    }
}
矩形的坐标创建正确,因为这是DayRectangle的ArrayList的内容:

它们从20开始,20因为我想在这些矩形之间留出一些间隙

主要问题是在执行此代码时没有打印矩形:

public void graph(JFrame frame) {
    buildBackground(frame);
    frame.getGraphics().setColor(Color.WHITE);
    JPanel panel;
    for (DayRectangle d : arraylist) {
        panel = d;
        frame.add(panel);
        frame.repaint();
    }
}

我做错了什么?为什么什么都没印?谢谢。

您似乎忘记了JFrame使用BorderLayout作为布局管理器。相反,您应该将您的Day JPanel添加到另一个使用GridLayout的JPanel中,并且还要记住,Day JPanel将相对于其自己的局部坐标系绘制,因此每天JPanel可能应该在相同的位置绘制其矩形,从0、0附近开始,而不是相对于包含的容器

如果希望一个JPanel成为背景JPanel,则应将其添加到BorderLayout.CENTER位置的JFrame中。给它一个GridLayout,并将你的Day JPanel添加到其中,如果你需要空的方块,任何需要空的JLabel都是空的。另外,若你们想让背景图像或颜色显示出来,白天可能需要不透明

e、 g

举个简单的例子:


你的回答真的很感谢!有了另一个答案,很明显GridLayout是解决我遇到的问题的明显选择哈哈,但是,有两件事我仍然不明白,你的程序怎么知道七月(如周三)开始?在我自己的程序中,我有保存在DayRectangle中的坐标信息,但现在我不知道如何设置网格的起始位置。另一件事是,您的示例中似乎缺少一些单词?在网格的构造函数底部和DayRectangle的构造函数中。再次感谢^^@hxsh.fx:我的程序不知道这一点,因为它只是一个简单的示例程序。我只添加了几个空白的jlabel,以显示日期可以改变。您需要添加逻辑,以便知道要添加多少JLabel(如果有的话)来填充网格的开头;topPanel.addmonthLabel,BorderLayout.PAGE_START;topPanel.AddDaysofWorkPanel,BorderLayout.CENTER;SetLayoutNewBorderLayout;addtopPanel,BorderLayout.PAGE_START;addmainGrid,BorderLayout.CENTER;和JLabel标签=新JLabel+天;label.setFontlabel.getFont.deriveFontFont.BOLD,FNT_SZ;addlabel@hxsh.fx:?不确定你在问什么?在ExampleGrid构造函数的底部有几行setLayout,add,add,我真的不知道对象是什么,topPanel.setLayout?在DayRectangle构造函数中,lanes设置Layout和add。
public void graph(JFrame frame) {
    buildBackground(frame);
    frame.getGraphics().setColor(Color.WHITE);
    JPanel panel;
    for (DayRectangle d : arraylist) {
        panel = d;
        frame.add(panel);
        frame.repaint();
    }
}
public class DayRectangle extends JPanel {
    private static Color RECT_COLOR = Color.LIGHT_GRAY;
    private static final int PREF_W = 60;
    private static final int GAP = 4;
    private int posX;
    private int posY;
    private int day;

    public DayRectangle(int posX, int posY, int day) {
        this.posX = posX; // not sure that you need this
        this.posY = posY; // ditto
        this.day = day;

        // if you desire a background to show throw
        // setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(RECT_COLOR);
        g.fillRect(GAP, GAP, PREF_W - 2 * GAP, PREF_W - 2 * GAP);
    }

    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_W);
    }

    @Override
    public String toString() {
        return String.format("(%d,%d):%d", posX, posY, day);
    }
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class ExampleGrid extends JPanel {
    public ExampleGrid() {

        JPanel mainGrid = new JPanel();
        mainGrid.setLayout(new GridLayout(0, 7));
        // just to show a little off-set of the days
        mainGrid.add(new JLabel());
        mainGrid.add(new JLabel());
        mainGrid.add(new JLabel());

        // now fill the calendar
        for (int i = 0; i < 30; i++) {
            mainGrid.add(new DayRectangle(i + 1));
        }

        JLabel monthLabel = new JLabel("JULY", SwingConstants.CENTER);
        monthLabel.setFont(monthLabel.getFont().deriveFont(Font.BOLD, 36f));

        // label the days of the week at the top
        String[] daysOfWk = { "Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat" };
        JPanel daysOfWkPanel = new JPanel(new GridLayout(1, 7));
        for (String dayOfWk : daysOfWk) {
            daysOfWkPanel.add(new JLabel(dayOfWk, SwingConstants.CENTER));
        }

        JPanel topPanel = new JPanel(new BorderLayout());
        topPanel.add(monthLabel, BorderLayout.PAGE_START);
        topPanel.add(daysOfWkPanel, BorderLayout.CENTER);

        setLayout(new BorderLayout());
        add(topPanel, BorderLayout.PAGE_START);
        add(mainGrid, BorderLayout.CENTER);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // not sure what you want to do here
    }

    private static void createAndShowGui() {
        ExampleGrid mainPanel = new ExampleGrid();

        JFrame frame = new JFrame("Example Grid");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class DayRectangle extends JPanel {
    private static Color RECT_COLOR = Color.LIGHT_GRAY;
    private static final int PREF_W = 60;
    private static final int GAP = 4;
    private static final float FNT_SZ = 20f;
    private int day;

    public DayRectangle(int day) {
        this.day = day;

        setLayout(new GridBagLayout());

        JLabel label = new JLabel("" + day);
        label.setFont(label.getFont().deriveFont(Font.BOLD, FNT_SZ));
        add(label);

        // if you desire a background to show throw
        // setOpaque(false);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(RECT_COLOR);
        g.fillRect(GAP, GAP, PREF_W - 2 * GAP, PREF_W - 2 * GAP);
    }

    public Dimension getPreferredSize() {
        return new Dimension(PREF_W, PREF_W);
    }

    public int getDay() {
        return day;
    }

}