【问题标题】:Created graphics object only showing once and disappears again after creating another one创建的图形对象只显示一次并在创建另一个后再次消失
【发布时间】:2022-01-17 09:06:03
【问题描述】:

对于我正在学习和使用 Java Swing 的当前项目。我希望我的程序创建圆角矩形,我目前正在使用 Graphics

我创建了一个JFrame 和一个菜单。两者都工作正常。当我单击菜单项“创建球体”时,您可以从ColorChooser 中选择一种颜色,定义名称、宽度、高度、x 和 y 位置。调用该方法后,我得到了我的 RoundedRectangle

当我想创建另一个时,它也可以,但是第一个消失了

调整框架大小后,第一个再次出现,但第二个正在消失。

代码:

JFrame:

public void createWindow() {
    /** Frame */
    this.setTitle("Diagram");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(700,500);
    this.setLocationRelativeTo(null);
    this.setVisible(true);
}

我的对话框框架调用了createSphere 方法,在这里我创建了一个新的Sphere(即RoundedRectangle)并将其添加到我的框架中:

public void createSphere(String name, int width, int height, int x, int y, Color color) {
    this.add(new Sphere(name, width, height, x, y, color));
    this.validate();
}

球类:

public class Sphere extends JPanel {
    private String name;
    private int width;
    private int height;
    private int xPos;
    private int yPos;
    private Color color;

    public Sphere(String name, int width, int height, int xPos, int yPos, Color color) {
        this.name = name;
        this.width = width;
        this.height = height;
        this.xPos = xPos;
        this.yPos = yPos;
        this.color = color;
    }

    public void paintComponent (Graphics g) {
        super.paintComponent(g);
        g.drawRoundRect(this.xPos,this.yPos,this.width,this.height, 15, 15);
        g.setColor(this.color);
        g.fillRoundRect(this.xPos,this.yPos,this.width,this.height, 15, 15);
    }

我希望我的程序创建几个 Sphere 对象。稍后,Sphere 对象也将包含几个较小的带有文本的Spheres。

【问题讨论】:

  • 使Sphere 成为一个普通的Java getter/setter 类。创建一个扩展JPanelDrawingPanel 类。创建一个DrawingModel 类作为一个普通的Java getter/setter 类,其中包含java.util.LIstSphere 对象。编写 DrawingPanel 类以在 paintComponent 方法中绘制 ListSphere 实例。
  • 在绘制图形之前面板会被清除,因此您只能看到最后绘制的图形。请参阅Custom Painting Approaches,了解进行增量绘制的两种常用方法,看看哪种方法最能满足您的要求。

标签: java swing graphics2d


【解决方案1】:

@camickr(在 cmets 部分)解释了为什么只绘制最后一个图形的原因。解决这个问题的一种方法是有一个单独的绘图面板(即下面的SpherePane)扩展JPanel(正如@Gilbert Le Blanc 也指出的那样),它将用于绘制一个球体对象列表。每次创建 Sphere 的新实例时,它都会添加到该列表中,并且每当调用 repaint() 时,该 Sphere 对象列表将在 SpherePanepaintComponent 方法中绘制。下面是一个示例,使用颜色选择器(如您在问题中提到的)添加固定大小的新 Sphere 对象(一旦选择颜色)并放置在随机位置(您可以用自己的代码替换这些对象)。

Main.java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;

public class Main extends JFrame {
    ArrayList<Sphere> list;
    JMenuBar menuBar;
    JMenuItem menuItemCreate;
    JColorChooser jColorChooser;
    SpherePane sp;
    int max = 500;
    int min = 10;

    public Main() {
        list = new ArrayList<Sphere>();
        sp = new SpherePane(list);
        menuBar = new JMenuBar();
        menuItemCreate= new JMenuItem("Create Sphere");
        menuBar.add(menuItemCreate);
        jColorChooser = new JColorChooser();
        addJCListener();
        createWindow();
    }

    private void addJCListener() {
        menuItemCreate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Color c = JColorChooser.showDialog(null, "", Color.BLUE);
                if (c != null) {
                    int x = ThreadLocalRandom.current().nextInt(min, max + 1);
                    int y = ThreadLocalRandom.current().nextInt(min, max + 1);
                    createSphere("", 100, 100, x, y, c);
                }
            }
        });
    }
    
    private void createWindow() {
        this.add(sp);
        this.setJMenuBar(menuBar);
        this.setSize(700,500);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setVisible(true);
    }

    public void createSphere(String name, int width, int height, int x, int y, Color color) {
        list.add(new Sphere(name, width, height, x, y, color));
        this.repaint();
        this.revalidate();
    }

    public static void main(String[] args) {
        new Main();
    }
}

SpherePane.java

import java.awt.Graphics;
import javax.swing.JPanel;
import java.util.ArrayList;

public class SpherePane extends JPanel {
    ArrayList<Sphere> list;

    public SpherePane(ArrayList<Sphere> list) {
        this.list = list;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Sphere s : list) {
            g.drawRoundRect(s.getxPos(), s.getyPos(), s.getWidth(), s.getHeight(), 15, 15);
            g.setColor(s.getColor());
            g.fillRoundRect(s.getxPos(), s.getyPos(), s.getWidth(), s.getHeight(), 15, 15);
        }

    }
}

Sphere.java

import java.awt.Color;

public class Sphere {
    private String name;
    private int width;
    private int height;
    private int xPos;
    private int yPos;
    private Color color;

    public Sphere(String name, int width, int height, int xPos, int yPos, Color color) {
        this.name = name;
        this.width = width;
        this.height = height;
        this.xPos = xPos;
        this.yPos = yPos;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public int getxPos() {
        return xPos;
    }

    public int getyPos() {
        return yPos;
    }

    public Color getColor() {
        return color;
    }
    
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多