2

我想画简单的椭圆形。在下面的代码中,如果我在 Jpanel 上添加了一个椭圆,那么它不起作用但是如果我在框架上绘制它就可以正常工作。以下是有效的代码。

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

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class Controller {

    public Controller() {
        View view = new View();
        Model model = new Model(100, 100, 100, 100);
        view.paintModel(model);
    }

    public static void main(String[] args) {
        Controller c = new Controller();
    }

    public class View extends JFrame {
        private JPanel jpanel;

        public View() {
            this.setBounds(0, 0, 500, 500);
            this.setLayout(new BorderLayout());

            jpanel = new JPanel();
            jpanel.setBackground(Color.WHITE);
            jpanel.setLayout(null);
            this.add(jpanel, BorderLayout.CENTER);

            this.setVisible(true);
            this.validate();
        }

        public void paintModel(Model model) {
            jpanel.add(new ModelView(model));
            jpanel.validate();
            jpanel.repaint();
        }

    }

    public class Model {
        public int xPos;
        public int yPos;
        public int height;
        public int width;

        public Model(int xPos, int yPos, int height, int width) {
            super();
            this.xPos = xPos;
            this.yPos = yPos;
            this.height = height;
            this.width = width;
        }
    }

    public class ModelView extends JComponent {

        private Model model;

        public ModelView(Model model) {
            super();
            setBorder(new LineBorder(Color.RED));
            this.model = model;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(model.xPos + model.width, model.yPos
                    + model.height);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.black);
            g.fillOval(model.xPos, model.yPos, model.width, model.height);
        }
    }

}
4

1 回答 1

4

首先,你没有super.paintComponent在你的ModelView类中调用,这非常重要,尤其是在处理透明组件时,比如JComponent

其次,您没有提供 的布局信息ModelView,也就是说,组件没有首选、最小或最大尺寸提示,因此许多布局管理器会认为它的尺寸为0x0,这就是这里发生的情况。

JPanel默认情况下使用FlowLayout它将使用组件的首选大小来布置它。

更新ModelView以提供一些尺寸提示(在大多数情况下,覆盖getPreferredSize应该就足够了)或在JPanel您添加的ModelView不关心此类事情的情况下使用不同的布局管理器(BorderLayout例如)

更新

此外,您“可能”正在超出组件的视觉范围进行绘画,例如,您使用创建模型,Model model = new Model(100, 100, 100, 100)然后使用 渲染该模型g.fillOval(model.xPos, model.yPos, model.width, model.height),但preferredSize您的组件只是new Dimension(model.width, model.height),您实际上是在右侧绘制椭圆,组件的下边缘(外侧)

除非您打算编写自己的布局管理器来管理它,否则在计算组件的首选大小时应该考虑 x/y 偏移量,例如,new Dimension(model.xPos + model.width, model.yPos + model.height)

例如...对不起,我对您的代码进行了一些处理以播种模型...

在此处输入图像描述

红线只是一个LineBorder显示ModelView组件边界的

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;

public class View extends JFrame {

    private JPanel jpanel;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                new View();

            }
        });
    }

    public View() {
        this.setBounds(0, 0, 500, 500);
        this.setLayout(new BorderLayout());

        jpanel = new JPanel();
        jpanel.setBackground(Color.WHITE);
        this.add(jpanel, BorderLayout.CENTER);

        Model model = new Model(100, 100, 100, 100);
        paintModel(model);

        this.setVisible(true);
    }

    public void paintModel(Model model) {
        jpanel.add(new ModelView(model));
        jpanel.validate();
        jpanel.repaint();
    }

    public class ModelView extends JComponent {

        private Model model;

        public ModelView(Model model) {
            super();
            setBorder(new LineBorder(Color.RED));
            this.model = model;
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(model.xPos + model.width, model.yPos + model.height);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.black);
            g.fillOval(model.xPos, model.yPos, model.width, model.height);
        }
    }

    public class Model {

        public int xPos;
        public int yPos;
        public int height;
        public int width;

        public Model(int xPos, int yPos, int height, int width) {
            super();
            this.xPos = xPos;
            this.yPos = yPos;
            this.height = height;
            this.width = width;
        }
    }
}
于 2013-11-01T01:09:06.777 回答