使用getGraphics()绘制对象而不扩展JFrame

时间:2023-02-09 15:43:00

How can I draw an object without a class (which extends JFrame)? I found getGraphics method but it doesnt draw the object.

如何在没有类(扩展JFrame)的情况下绘制对象?我找到了getGraphics方法,但它没有绘制对象。

import javax.swing.*;
import java.awt.*;
public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(600, 400);

        JPanel panel = new JPanel();
        frame.add(panel);

        Graphics g = panel.getGraphics();
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 100, 100);
    }
}

3 个解决方案

#1


21  

If you want to change the way your component is being drawn (you are adding rectangles), you need to redefine paintComponent() in that component. In your code, you are using getGraphics().

如果要更改绘制组件的方式(添加矩形),则需要在该组件中重新定义paintComponent()。在您的代码中,您使用的是getGraphics()。

You shouldn't call getGraphics() on a component. Any painting you do (to the Graphics returned) will be temporary and will be lost the next time Swing determines a component needs to be repainted.

您不应该在组件上调用getGraphics()。你做的任何绘画(对于返回的图形)将是临时的,并且在下次Swing确定需要重新绘制组件时将丢失。

Instead, you should override the paintComponent(Graphics) method (of the JComponent or JPanel), and do the painting in this method, using the Graphics object received as argument.

相反,您应该覆盖paintComponent(Graphics)方法(JComponent或JPanel),并使用作为参数接收的Graphics对象在此方法中进行绘制。

Check this link for further reading.

请查看此链接以进一步阅读。

Below is your code, corrected.

以下是您的代码,已更正。

import javax.swing.*;
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(600, 400);

        JPanel panel = new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, 100, 100);
            }
        };
        frame.add(panel);

        // Graphics g = panel.getGraphics();
        // g.setColor(Color.BLUE);
        // g.fillRect(0, 0, 100, 100);

        frame.validate(); // because you added panel after setVisible was called
        frame.repaint(); // because you added panel after setVisible was called
    }
}

Another version, does the exact same thing, but may be clearer to you:

另一个版本,完全相同,但可能更清楚:

import javax.swing.*;
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(600, 400);

        JPanel panel = new MyRectangleJPanel(); // changed this line
        frame.add(panel);

        // Graphics g = panel.getGraphics();
        // g.setColor(Color.BLUE);
        // g.fillRect(0, 0, 100, 100);

        frame.validate(); // because you added panel after setVisible was called
        frame.repaint(); // because you added panel after setVisible was called
    }
}

/* A JPanel that overrides the paintComponent() method and draws a rectangle */
class MyRectangleJPanel extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 100, 100);
    }
}

#2


4  

You have to override paintComponent method in JPanel class. So you should create a class which extends JPanel and override paintComponent method in subclass

您必须覆盖JPanel类中的paintComponent方法。因此,您应该创建一个扩展JPanel并在子类中覆盖paintComponent方法的类

#3


2  

java.awt.image.BufferedImage


Why not just use an instance of java.awt.image.BufferedImage? e.g.

为什么不使用java.awt.image.BufferedImage的实例?例如

BufferedImage output = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = output.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
    RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, output.getWidth(), output.getHeight());
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 100, 100);

JOptionPane.showMessageDialog(null, new ImageIcon(output));

#1


21  

If you want to change the way your component is being drawn (you are adding rectangles), you need to redefine paintComponent() in that component. In your code, you are using getGraphics().

如果要更改绘制组件的方式(添加矩形),则需要在该组件中重新定义paintComponent()。在您的代码中,您使用的是getGraphics()。

You shouldn't call getGraphics() on a component. Any painting you do (to the Graphics returned) will be temporary and will be lost the next time Swing determines a component needs to be repainted.

您不应该在组件上调用getGraphics()。你做的任何绘画(对于返回的图形)将是临时的,并且在下次Swing确定需要重新绘制组件时将丢失。

Instead, you should override the paintComponent(Graphics) method (of the JComponent or JPanel), and do the painting in this method, using the Graphics object received as argument.

相反,您应该覆盖paintComponent(Graphics)方法(JComponent或JPanel),并使用作为参数接收的Graphics对象在此方法中进行绘制。

Check this link for further reading.

请查看此链接以进一步阅读。

Below is your code, corrected.

以下是您的代码,已更正。

import javax.swing.*;
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(600, 400);

        JPanel panel = new JPanel() {
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, 100, 100);
            }
        };
        frame.add(panel);

        // Graphics g = panel.getGraphics();
        // g.setColor(Color.BLUE);
        // g.fillRect(0, 0, 100, 100);

        frame.validate(); // because you added panel after setVisible was called
        frame.repaint(); // because you added panel after setVisible was called
    }
}

Another version, does the exact same thing, but may be clearer to you:

另一个版本,完全相同,但可能更清楚:

import javax.swing.*;
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setSize(600, 400);

        JPanel panel = new MyRectangleJPanel(); // changed this line
        frame.add(panel);

        // Graphics g = panel.getGraphics();
        // g.setColor(Color.BLUE);
        // g.fillRect(0, 0, 100, 100);

        frame.validate(); // because you added panel after setVisible was called
        frame.repaint(); // because you added panel after setVisible was called
    }
}

/* A JPanel that overrides the paintComponent() method and draws a rectangle */
class MyRectangleJPanel extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 100, 100);
    }
}

#2


4  

You have to override paintComponent method in JPanel class. So you should create a class which extends JPanel and override paintComponent method in subclass

您必须覆盖JPanel类中的paintComponent方法。因此,您应该创建一个扩展JPanel并在子类中覆盖paintComponent方法的类

#3


2  

java.awt.image.BufferedImage


Why not just use an instance of java.awt.image.BufferedImage? e.g.

为什么不使用java.awt.image.BufferedImage的实例?例如

BufferedImage output = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);

Graphics2D g2 = output.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
    RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, output.getWidth(), output.getHeight());
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 100, 100);

JOptionPane.showMessageDialog(null, new ImageIcon(output));