如何在一个框架中添加多个paintComponent()? [英] How can I add more than one paintComponent() to a frame?

查看:77
本文介绍了如何在一个框架中添加多个paintComponent()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的主要课程:

  package testgame;导入java.awt.EventQueue;导入javax.swing.JFrame;公共类Game扩展了JFrame {公共静态JFrame frame = new JFrame("Just a test!");公共静态void LoadUI(){frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);frame.setSize(550,500);frame.setLocationRelativeTo(null);frame.setVisible(true);}公共静态void main(String [] args){LoadUI();frame.add(new Circles());}} 

这是处理我要绘制的内容的类:

  package testgame;导入java.awt.BasicStroke;导入java.awt.Color;导入java.awt.Dimension;导入java.awt.Graphics;导入java.awt.Graphics2D;导入java.awt.RenderingHints;导入java.awt.geom.AffineTransform;导入java.awt.geom.Ellipse2D;导入javax.swing.JPanel;导入javax.swing.SwingUtilities;导入javax.swing.Timer;公共类Circles扩展了JPanel {@Overridepublic void paintComponent(Graphics g){super.paintComponent(g);drawBubbles(g);}public void drawBubbles(Graphics g){Graphics2D g2d =(Graphics2D)g;RenderingHints rh= new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);rh.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);g2d.setRenderingHints(rh);整数x,y,大小;x =(int)(Math.random()* 500)+ 15;y =(int)(Math.random()* 450)+ 15;大小=(int)(Math.random()* 50)+ 25;g2d.setColor(Color.GREEN);g2d.drawOval(x,y,size,size);g2d.fillOval(x,y,size,size);}} 

如果我添加另一个

  frame.add(new Circles()); 

什么都没发生.我认为这与框架的布局有关,但是气泡的坐标是随机的,因此我不确定如何使用它.

解决方案

在这种情况下,我使用的固定大小为5的数组,您可以将其更改为更大的固定大小的数组或 ArrayList ,如

我希望这可以帮助您获得更好的主意,在我将MVC模式用于此答案时,请阅读有关MVC模式的信息.


注意:

在此答案中,根据@MadProgrammer在此课程:执行自定义绘画在AWT和Swing中进行绘画教程.

So this is my main class:

package testgame;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class Game extends JFrame {

public static JFrame frame = new JFrame("Just a test!");

public static void LoadUI() {
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    frame.setSize(550, 500);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true); }

public static void main(String[] args) {
    LoadUI();
    frame.add(new Circles());
    }
}

And this is the class that handles what I want to paint:

package testgame;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class Circles extends JPanel {

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    drawBubbles(g); }

public void drawBubbles(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    RenderingHints rh
            = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    rh.put(RenderingHints.KEY_RENDERING, 
            RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHints(rh);
    int x, y, size;
    x = (int) (Math.random() * 500) + 15;
    y = (int) (Math.random() * 450) + 15;
    size = (int) (Math.random() * 50) + 25;
    g2d.setColor(Color.GREEN);
    g2d.drawOval(x, y, size, size);
    g2d.fillOval(x, y, size, size); }
}

If I add another

 frame.add(new Circles());

Nothing happens. I think it has to do with the layout of the frame, but the coordinates of the bubbles are random so I'm not sure how to work with this.

解决方案

In this case I'm using a fixed-size array of 5, you may change it to a bigger fixed-size array or an ArrayList, as shown in this answer

For your particular case I would create a Circle class that may contain the data for each circle, being the coords and the size

Then create a CirclePane class that would paint all the Circles in a single paintComponent() method.

And finally, the Main class that would have a JFrame that may contain the CirclePane added to it.

With the above tips in mind, you could end up with something like this:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class CircleDrawer {
    private JFrame frame;
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new CircleDrawer()::createAndShowGui); //We place our program on the EDT
    }
    
    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());
        
        CirclePane circle = new CirclePane(5); //We want to create 5 circles, we may want to add more so we change it to 10, or whatever number we want
        
        frame.add(circle);
        
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    //Data class
    class Circle {
        private Point coords;
        private int size;
        
        public Circle(Point coords, int size) {
            this.coords = coords;
            this.size = size;
        }
        
        public Point getCoords() {
            return coords;
        }
        public void setCoords(Point coords) {
            this.coords = coords;
        }
        public int getSize() {
            return size;
        }
        public void setSize(int size) {
            this.size = size;
        }
    }
    
    //The drawing class
    @SuppressWarnings("serial")
    class CirclePane extends JPanel {
        private int numberOfCircles;
        private Circle[] circles;

        public CirclePane(int numberOfCircles) {
            this.numberOfCircles = numberOfCircles;
            
            circles = new Circle[numberOfCircles];
            
            for (int i = 0; i < numberOfCircles; i++) {
                Point coords = new Point((int) (Math.random() * 500) + 15, (int) (Math.random() * 450) + 15); //We generate random coords
                int size = (int) (Math.random() * 50) + 25; //And random sizes
                circles[i] = new Circle(coords, size); //Finally we create a new Circle with these properties
            }
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            
            for (int i = 0; i < numberOfCircles; i++) {
                g2d.draw(new Ellipse2D.Double(circles[i].getCoords().getX(), circles[i].getCoords().getY(), circles[i].getSize(), circles[i].getSize())); //We iterate over each circle in the array and paint it according to its coords and sizes
            }
        }
        
        @Override
        public Dimension getPreferredSize() { //Never call JFrame.setSize(), instead override this method and call JFrame.pack()
            return new Dimension(500, 500);
        }
    }
}

Which produces a similar output to this:

I hope this helps you to get a better idea, read about the MVC pattern as I made use of it for this answer.


Note:

In this answer I used the Shapes API, according to the recommendation of @MadProgrammer in this other answer. I used it in the g2d.draw(...) line.

For a deeper understanding in how custom painting works in Swing, check Oracle's Lesson: Performing Custom Painting and Painting in AWT and Swing tutorials.

这篇关于如何在一个框架中添加多个paintComponent()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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