如何编写一个JPanel,以使图形始终可见?

huangapple go评论59阅读模式
英文:

How do I program a JPanel such that the graphics are always visible?

问题

"JPanel graphics are not fully visible [tag:swing]"
"当我将此面板添加到包含另一个组件的主面板时,我只能看到网格的右上角。如何使所有图形都可见?"

英文:

JPanel graphics are not fully visible [tag:swing]

I am attempting to program an event scheduling system. I have coded a SchedulePanel class that contains a grid that I drew directly onto the panel.

public class SchedulePanel extends JPanel {

		private static final long serialVersionUID = 1L;

		static final int originX = 0;
		static final int originY = 0;
		static final int cellSide = 50;

		static final int cols = 5;
		static final int rows = 5;

		public SchedulePanel() {
			setMinimumSize(new Dimension(cols * cellSide, rows * cellSide));
			setBackground(Color.LIGHT_GRAY);
		}

		@Override
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			// this for loop draws horizontal lines that separate the rows in
			// the
			// grid
			for (int i = 0; i < rows; i++) {
				g.drawLine(originX, originY + (i * cellSide),
						originX + (cols * cellSide), originY + (i * cellSide));
			}
			// this for loop draws vertical lines that separate the columns in
			// the
			// grid
			for (int i = 0; i < cols; i++) {
				g.drawLine(originX + (i * cellSide), originY,
						originX + (i * cellSide), originY + (rows * cellSide));
			}

		}
	}

When I add this panel to the main panel containig another component I can only see the top right corner of the grid. How do I make it so that all of my graphics are visible?

public class EventSchedulerGUI extends JPanel {

	RoomPanel roomPanel;
	SchedulePanel schedulePanel;
	JList<Room> roomList;

	public EventSchedulerGUI() {
		FlowLayout layout = new FlowLayout();
		setLayout(layout);
		roomPanel = new RoomPanel();

		schedulePanel = new SchedulePanel();
		schedulePanel.setMinimumSize(new Dimension(400, 400));

		add(roomPanel);
		add(schedulePanel);

	}

答案1

得分: -1

你的组件应该定义其可接受的大小提示,然后布局管理器将使用这些提示来决定如何最佳布局您的组件。

作为起点,您应该重写 getPreferredSize,例如...

public class SchedulePanel extends JPanel {

    private static final long serialVersionUID = 1L;

    static final int originX = 0;
    static final int originY = 0;
    static final int cellSide = 50;

    static final int cols = 5;
    static final int rows = 5;

    public SchedulePanel() {
        setMinimumSize(new Dimension(cols * cellSide, rows * cellSide));
        setBackground(Color.LIGHT_GRAY);
    }

    @Override
    public Dimension getPreferredSize() {
        // 通常,我更喜欢根据组件和其数据的需求来计算这个值,但你明白我的意思
        return new Dimension(400, 400);
    }

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(400, 400);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // 这个循环用于绘制网格中分隔行的水平线
        for (int i = 0; i < rows; i++) {
            g.drawLine(originX, originY + (i * cellSide),
                    originX + (cols * cellSide), originY + (i * cellSide));
        }
        // 这个循环用于绘制网格中分隔列的垂直线
        for (int i = 0; i < cols; i++) {
            g.drawLine(originX + (i * cellSide), originY,
                    originX + (i * cellSide), originY + (rows * cellSide));
        }

    }
}

为什么要使用 override 而不是调用 setXxxSize

因为这是组件的责任来做出这些决定,而不是调用者的责任。调用者的责任是找出如何容纳它们。

此外,您不希望有人随意修改大小提示,因为那只会搞乱一切。

英文:

Your component should be defining it's acceptable sizing hints, these are then used by the layout managers to make decisions about how best to layout your component.

As a starting point, you should override getPreferredSize, for example...

public class SchedulePanel extends JPanel {
private static final long serialVersionUID = 1L;
static final int originX = 0;
static final int originY = 0;
static final int cellSide = 50;
static final int cols = 5;
static final int rows = 5;
public SchedulePanel() {
setMinimumSize(new Dimension(cols * cellSide, rows * cellSide));
setBackground(Color.LIGHT_GRAY);
}
@Override
public Dimension getPreferredSize() {
// I generally prefer to calculate this based on the
// needs of the component and it&#39;s data, but you get the
// idea
return new Dimension(400, 400);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(400, 400);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// this for loop draws horizontal lines that separate the rows in
// the
// grid
for (int i = 0; i &lt; rows; i++) {
g.drawLine(originX, originY + (i * cellSide),
originX + (cols * cellSide), originY + (i * cellSide));
}
// this for loop draws vertical lines that separate the columns in
// the
// grid
for (int i = 0; i &lt; cols; i++) {
g.drawLine(originX + (i * cellSide), originY,
originX + (i * cellSide), originY + (rows * cellSide));
}
}
}

Why override instead of calling setXxxSize?

Because it's the component's responsibility to make these determinations, not the callers. It's the callers responsibility to figure out how to accomodate them.

Also, you don't want someone coming along and modifying the sizing hints, that just messes everything up.

huangapple
  • 本文由 发表于 2023年5月25日 07:35:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76328008.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定