添加到 JPanel 的项目不显示 [英] Added items to JPanel dont' show up

查看:148
本文介绍了添加到 JPanel 的项目不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望有人能帮我解决这个问题.我真的找不到任何人来描述这个确切的问题.在扩展 JFrame 的主类 (Window) 中,我添加了一个扩展 JPanel 的类 (Panel) 的对象> 并将其添加到我的框架中.

I was hoping anyone could help me with this. I can't really find anyone describing this exact issue. In my main class (Window) that extends JFrame I add an object of a class (Panel) that extends JPanel and add it to my frame.

到目前为止一切都很好,JPanel 类中的所有内容都按预期显示,但是当我在主类中创建 ShapeDef 对象(用于定义和绘制图形),然后尝试将其添加到Panel,数字不会显示.为什么?我尝试使用 revalidate()repaint,但它似乎不起作用.

So far so good, everything in the JPanel class shows up as they should, but when I in my main class create ShapeDef object (used to define and draw figures), and then try to add it to the Panel, the figures won't show up. Why? I tried using revalidate() and repaint, but it doesn't seem to work.

这是一些代码:

主类:

public class Window extends JFrame implements ActionListener{

private JPanel myPanel;
private ShapeDef rect1, rect2;

public Window(){
    super("Test Window");
    setLayout(new BorderLayout());

    myPanel = new Panel(new BorderLayout()); 
    myPanel.setBackground(Color.BLACK);

    rect1 = new ShapeDef("Rectangle", Color.green, 200, 300, 20, 80);
    rect2 = new ShapeDef("Rectangle", Color.BLUE, 300, 700, 50, 40);
    myPanel.add(rect1);
    myPanel.add(rect2);

    add(myPanel, BorderLayout.CENTER);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            JFrame myFrame = new PongInvaders();
            myFrame.setSize(1280, 720);
            myFrame.setBackground(Color.BLACK);
            myFrame.pack();
            myFrame.setVisible(true);
        }
    });
}

ShapeDef 类:

ShapeDef class:

public class ShapeDef extends JComponent{
    private final Color color;
    private final int x, y, width, height;
    private final String type;

    public ShapeDef(String type, Color color, int x, int y, int width, int height){
        this.type = type;
        this.color = color;
        setBounds(x, y, width, height);
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;

    }

        @Override
        public void paintComponent(Graphics g){
        super.paintComponent(g);
        if(type.equalsIgnoreCase("Rectangle")){
            g.setColor(color);
            g.fillRect(0, 0, width, height);
        }
        else if(type.equalsIgnoreCase("Oval")){
            g.setColor(color);
            g.fillOval(x, y, width, height);
        }
    }
}

李克强建议的当前版本的代码绘制了两个矩形,但 rect2 在 (0,0) 处生成,而 rect1 在正确的坐标处生成.所以基本上问题得到了回答,所以谢谢大家的帮助.但是,当它们都添加到同一个 JPanel 时,为什么只有一个矩形在 (0,0) 处生成而另一个在设置坐标处生成?

The current version of the code suggested by Keqiang Li draws both of the rectangles, but rect2 spawns at (0,0) while rect1 spawns at the correct coordinates. So basically the question is answered, so thank you all for your help. However why is it that only one of the rectangles spawn at (0,0) while the other spawns at set coordinates, when they're both added to the same JPanel?

@MadProgrammer 虽然您的回答不是我所期望的,但我认为这是我需要的.你绝对不辜负你的用户名.非常感谢您花时间教我更多关于创建更好的代码结构的知识.

@MadProgrammer Although your answer was not the one I expected, I think it's the one I needed. You definitely live up to your user name. Thank you so much for taking the time to teach me a little more about creating a better code structure.

我还想指出,其他答案非常有帮助和启发性,它们也教会了我很多.

I would also like to point out that the other answers were very helpful and enlightening, and that they also taught me alot.

推荐答案

就我个人而言,我认为您从错误的角度接近解决方案.组件并不是真正设计来做到这一点的,当然你可以让它们做到这一点,但它会引出一些有趣的路径,如果你不小心,可能会让你流血.

Personally, I think you're approaching the solution from the wrong angle. Components aren't really designed to do this, sure you can make them do it, but it leads down some interesting paths which could have you bleeding in the gutter if you're not careful.

相反,我会定义一个可以绘制"的基本"形状,然后定义所有其他形状.

Instead, I'd define a "basic" shape which can be "painted" and from, define all you other shapes.

public interface Drawable {
    public Color getStrokeColor();
    public Color getFillColor();
    public Rectangle getBounds();
    public void paint(Graphics2D g2d);
}

public abstract class AbstractDrawable implements Drawable {

    private Color strokeColor;
    private Color fillColor;

    public AbstractDrawable(Color strokeColor, Color fillColor) {
        this.strokeColor = strokeColor;
        this.fillColor = fillColor;
    }

    @Override
    public Color getStrokeColor() {
        return strokeColor;
    }

    @Override
    public Color getFillColor() {
        return fillColor;
    }

}

public class RectangleDrawable extends AbstractDrawable {

    private Rectangle bounds;

    public RectangleDrawable(int x, int y, int width, int height, Color strokeColor, Color fillColor) {
        super(strokeColor, fillColor);
        bounds = new Rectangle(x, y, width, height);
    }

    @Override
    public Rectangle getBounds() {
        return bounds;
    }

    @Override
    public void paint(Graphics2D g2d) {
        g2d.setColor(getFillColor());
        g2d.fill(getBounds());
        g2d.setColor(getStrokeColor());
        g2d.draw(getBounds());
    }

}

public class OvalDrawable extends AbstractDrawable {

    private Ellipse2D bounds;

    public OvalDrawable(int x, int y, int width, int height, Color strokeColor, Color fillColor) {
        super(strokeColor, fillColor);
        bounds = new Ellipse2D.Double(x, y, width, height);
    }

    @Override
    public Rectangle getBounds() {
        return bounds.getBounds();
    }

    @Override
    public void paint(Graphics2D g2d) {
        g2d.setColor(getFillColor());
        g2d.fill(bounds);
        g2d.setColor(getStrokeColor());
        g2d.draw(bounds);
    }

}

然后我会有一个专门的组件来管理和绘制它们

I'd then have a dedicated component which was capable of managing and painting them

public class DrawablePane extends JPanel {

    private List<Drawable> drawables;

    public DrawablePane() {
        drawables = new ArrayList<>(25);
    }

    public void add(Drawable drawable) {
        drawables.add(drawable);
        repaint();
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        for (Drawable drawable : drawables) {
            drawable.paint(g2d);
        }
        g2d.dispose();
    }

}

可能会使用诸如...

EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
        }

        DrawablePane pane = new DrawablePane();
        pane.add(new RectangleDrawable(10, 10, 100, 150, Color.YELLOW, Color.GREEN));
        pane.add(new OvalDrawable(100, 20, 50, 50, Color.MAGENTA, Color.BLUE));

        JFrame frame = new JFrame("Testing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(pane);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
});

这篇关于添加到 JPanel 的项目不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆