正确绘制图像 [英] Properly drawing over an image

查看:79
本文介绍了正确绘制图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个小型图像编辑器,现在我正试图给用户提供通过拖动鼠标来绘制图像的机会(就像MS Paint中的铅笔工具一样).

我遇到了一些困难,因为当我太快地移动光标时,应用程序无法绘制所有应该着色的像素,只有一小部分是正确着色的.

我尝试了两种添加彩色像素的解决方案:首先,我创建了一个列表,其中存储了 mouseDragged 被调用时添加的所有点.之后,我决定在 BufferedImage 对象上简单地使用 setRGB ,因为它似乎并不慢.

我还进行了一项测试,以了解 mouseMoved 方法是否能够检测到光标悬停的所有点,如果我创建了一个列表并将其添加到每个列表中,则结果为负一点,当我打印列表时,里面只有一些点.

我认为我可以再次使用ImagePanel类上的列表,以在列表中包含的点之间使用 drawLine 方法,以尝试填补空白,但是我不认为这是一个很好的解决方案,因为如果图像放大了,我将需要重新发明drawLine方法,并且还需要找到最佳时机将所有点绘制到图像上.

有更好的解决方案吗?感谢您的帮助!

下面我发布了MVCE(我从图像编辑器中删除了所有工具,而且应用程序的设计也很差):

  import java.awt.*;导入java.awt.event.*;导入java.awt.image.BufferedImage;导入java.net.URL;导入java.util.ArrayList;导入javax.imageio.ImageIO;导入javax.swing.*;导入javax.swing.border.*;公共类ImageEditor{public static void main(String [] a){SwingUtilities.invokeLater(新的Runnable(){@Override public void run(){createAndShowGUI();}});}私人静态void createAndShowGUI(){JFrame frame =新的JFrame(图像编辑器");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setContentPane(新的MainPanel());frame.setExtendedState(JFrame.MAXIMIZED_BOTH);frame.pack();frame.setLocationRelativeTo(null);frame.setVisible(true);}}MainPanel类扩展了JPanel{//私有ArrayList< Point>points =新的ArrayList< Point>();私人ImagePanel imagePanel;私有ZoomPanel zoomPanel;公共MainPanel(){超级(新的BorderLayout());//-鼠标适配器-MouseAdapter mouseAdapter =新的MouseAdapter(){@Override public void mouseDragged(MouseEvent e){如果(SwingUtilities.isLeftMouseButton(e))imagePanel.setPixelColor(e.getX(),e.​​getY());}/* @Override public void mouseMoved(MouseEvent e){points.add(e.getPoint());} */@Override public void mouseReleased(MouseEvent e){//for(Point p:points)System.out.println(p);如果(SwingUtilities.isLeftMouseButton(e))imagePanel.setPixelColor(e.getX(),e.​​getY());}};//-图片面板-imagePanel =新的ImagePanel();imagePanel.addMouseMotionListener(mouseAdapter);imagePanel.addMouseListener(mouseAdapter);//-图像面板视图-JPanel imagePanelView =新的JPanel(新的FlowLayout(FlowLayout.LEFT,20,20));imagePanelView.add(imagePanel);//-图像面板滚动窗格-JScrollPane scrollPane =新的JScrollPane(imagePanelView);scrollPane.addMouseWheelListener(新的MouseWheelListener(){@Override public void mouseWheelMoved(MouseWheelEvent e){如果(e.isControlDown()){int rotation = e.getWheelRotation();if((旋转< 0& amp; imagePanel.zoomIn())||(旋转< 0& amp; imagePanel.zoomOut()))zoomPanel.zoomLevelChanged();}}});scrollPane.getHorizo​​ntalScrollBar().setUnitIncrement(100);scrollPane.getVerticalScrollBar().setUnitIncrement(100);scrollPane.setBorder(新的EmptyBorder(0,0,0,0));//-正在加载图片-尝试 {imagePanel.setImage(ImageIO.read(新URL("https://spotlight.it-notes.ru/wp-content/uploads/2016/10/255b4aa1455158ffde176a1e814c634f.jpg")));}捕获(异常e){e.printStackTrace();}//-底部面板-JPanel bottomPanel =新的JPanel(新的BorderLayout(100,0));bottomPanel.add(zoomPanel =新的ZoomPanel(imagePanel),BorderLayout.EAST);bottomPanel.setBorder(新的MatteBorder(1、0、0、0,getBackground().darker()));//-添加组件-添加(scrollPane,BorderLayout.CENTER);添加(bottomPanel,BorderLayout.SOUTH);}}ImagePanel类扩展了JPanel{private int zoomLevel;私有BufferedImage图像;private int rgb = Color.YELLOW.getRGB();//私有ArrayList< Point>DrawnPoints;公共ImagePanel(){超级(新的FlowLayout(FlowLayout.LEFT,0,0));zoomLevel = 1;//drawnPoints = new ArrayList< Point>();}受保护的BufferedImage getImage(){如果(image == null)返回null;//返回原始图像的副本.BufferedImage复制=新的BufferedImage(image.getWidth(),image.getHeight(),image.getType());Graphics2D g = copy.createGraphics();g.drawImage(image,0,0,null);g.dispose();返回副本;}受保护的int getImageHeight(){如果(image == null)返回0;返回image.getHeight();}受保护的int getImageWidth(){如果(image == null)返回0;返回image.getWidth();}@Override public Dimension getPreferredSize(){if(image == null)返回新尺寸(0,0);返回新的Dimension(image.getWidth()* zoomLevel,image.getHeight()* zoomLevel);}public int getZoomLevel(){返回zoomLevel;}@Override受保护的void paintComponent(图形g){super.paintComponent(g);g.drawImage(image,0,0,image.getWidth()* zoomLevel,image.getHeight()* zoomLevel,this);//if(drawnPoints!= null){//g.setColor(Color.YELLOW);//for(Point point:DrawnPoints)g.fillRect(point.x * zoomLevel,point.y * zoomLevel,zoomLevel,zoomLevel);//}}私人无效刷新(){容器父代= getParent();parent.revalidate();parent.repaint();}受保护的void setImage(BufferedImage图片){this.image =图片;刷新 ();}受保护的void setPixelColor(int scaledX,int scaledY){int x = scaledX/zoomLevel,y = scaledY/zoomLevel;if(x> = 0& y> = 0& x< image.getWidth()& y< image.getHeight()){//drawnPoints.add(新Point(x,y));image.setRGB(x,y,rgb);刷新 ();}}受保护的布尔缩放(int zoomLevel){如果(image == null || zoomLevel< 1 || zoomLevel> 8)返回false;否则,返回false.this.zoomLevel = zoomLevel;刷新 ();返回true;}受保护的布尔zoomIn(){返回图片!= null&&缩放(zoomLevel + 1);}受保护的boolean zoomOut(){返回图片!= null&&缩放(zoomLevel-1);}}ZoomPanel类扩展了JPanel{私人ImagePanel imagePanel;私人JLabel标签;受保护的ZoomPanel(ImagePanel imagePanel){超级(新的FlowLayout(FlowLayout.RIGHT,20,0));this.imagePanel = imagePanel;添加(标签=新的JLabel("100%"));添加(新的JButton(新的AbstractAction(-")){@Override public void actionPerformed(ActionEvent e){如果(imagePanel.zoomOut())zoomLevelChanged();}}));添加(新的JButton(新的AbstractAction("+")){@Override public void actionPerformed(ActionEvent e){如果(imagePanel.zoomIn())zoomLevelChanged();}}));setBorder(新的EmptyBorder(3,0,3,20));}protected void zoomLevelChanged(){label.setText(String.valueOf(imagePanel.getZoomLevel()* 100)+%");}} 

下面是显示问题的屏幕截图:

编辑

感谢@ug_和@MadProgrammer的解释和建议.正如我在原始帖子中所讲的那样,我已经考虑过使用drawLine方法,但是我无法弄清楚如何解决上面提到的问题.

现在,我意识到,如果缩放图像,则通过获取原始图像的图形在原始图像上使用drawLine非常简单,而且我完全不需要保留以后要绘制的点的列表,因为我只需要保留最后一点(就像@ug_在他的代码中一样).

我编辑我的代码,我只发布已更新的块:

在MainPanel构造函数中:

  MouseAdapter mouseAdapter =新的MouseAdapter(){@Override public void mouseDragged(MouseEvent e){如果(SwingUtilities.isLeftMouseButton(e))imagePanel.addPoint(e.getX(),e.​​getY());}@Override public void mouseReleased(MouseEvent e){如果(SwingUtilities.isLeftMouseButton(e))imagePanel.setPixelColor(e.getX(),e.​​getY());}}; 

ImagePanel类:

  class ImagePanel扩展了JPanel{private int zoomLevel;私有BufferedImage图像;private int rgb = Color.YELLOW.getRGB();私有Point lastPoint;公共ImagePanel(){超级(新的FlowLayout(FlowLayout.LEFT,0,0));zoomLevel = 1;}受保护的void addPoint(int scaledX,int scaledY){int x = scaledX/zoomLevel,y = scaledY/zoomLevel;if(x> = 0& y> = 0& x< image.getWidth()& y< image.getHeight()){如果(lastPoint == null)image.setRGB(x,y,rgb);别的 {Graphics2D g = image.createGraphics();g.setColor(Color.YELLOW);g.drawLine(lastPoint.x,lastPoint.y,x,y);g.dispose();}lastPoint =新点(x,y);刷新 ();}}受保护的int getImageHeight(){如果(image == null)返回0;返回image.getHeight();}受保护的int getImageWidth(){如果(image == null)返回0;返回image.getWidth();}@Override public Dimension getPreferredSize(){if(image == null)返回新尺寸(0,0);返回新的Dimension(image.getWidth()* zoomLevel,image.getHeight()* zoomLevel);}public int getZoomLevel(){返回zoomLevel;}@Override受保护的void paintComponent(图形g){super.paintComponent(g);g.drawImage(image,0,0,image.getWidth()* zoomLevel,image.getHeight()* zoomLevel,this);}私人无效刷新(){容器父代= getParent();parent.revalidate();parent.repaint();}受保护的void setImage(BufferedImage图片){this.image =图片;刷新 ();}受保护的void setPixelColor(int scaledX,int scaledY){int x = scaledX/zoomLevel,y = scaledY/zoomLevel;if(x> = 0& y> = 0& x< image.getWidth()& y< image.getHeight()){lastPoint = null;image.setRGB(x,y,rgb);刷新 ();}}受保护的布尔缩放(int zoomLevel){如果(image == null || zoomLevel< 1 || zoomLevel> 8)返回false;否则,返回false.this.zoomLevel = zoomLevel;刷新 ();返回true;}受保护的布尔zoomIn(){返回图片!= null&&缩放(zoomLevel + 1);}受保护的boolean zoomOut(){返回图片!= null&&缩放(zoomLevel-1);}} 

现在可以正常工作了!

解决方案

您不会为鼠标移过的每个像素获得鼠标事件,如果您快速移动鼠标,则尤其如此.我试图找到一些很好的文档来说明为什么这是成功的但不能成功.您可能会在

I'm creating a small image editor and right now i'm trying to give the user the chance of drawing over the image by dragging the mouse (like pencil tool in MS Paint does).

I'm having some difficulties since, when i move the cursor too fast, the application can't draw all the pixels which should be colored, just a little number is correctly colored.

I tried two solutions to add the colored pixels: at first i created a list where i stored all the points added when mouseDragged was called. After that i decided to simply use setRGB on BufferedImage object, since it does not seem to be slower.

I also made a test to understand if mouseMoved method is able to detect all the points which are hovered by cursor, and i had a negative result, if i create a list and add to it every point, when i print the list there are just some points in it.

I thought i could use again the list on ImagePanel class to use drawLine method between the points which are contained in the list, to try to fill the empty gap, but i don't think it's a good solution, because if the image is zoomed i would need to re-invent the drawLine method and i would also need to find the best moment to draw all the points to the image.

Is there some better solution? Any help is appreciated!

Below i post my MVCE (i removed all the tools from the image editor, also the design of the application is very poor):

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.*;
public class ImageEditor
{
    public static void main (String [] a) {
        SwingUtilities.invokeLater (new Runnable () {
            @Override public void run () {
                createAndShowGUI ();
            }
        });
    }
    private static void createAndShowGUI () {
        JFrame frame = new JFrame ("Image Editor");
        frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        frame.setContentPane (new MainPanel ());
        frame.setExtendedState (JFrame.MAXIMIZED_BOTH);
        frame.pack ();
        frame.setLocationRelativeTo (null);
        frame.setVisible (true);
    }
}
class MainPanel extends JPanel
{
    // private ArrayList <Point> points = new ArrayList <Point> ();
    private ImagePanel imagePanel;
    private ZoomPanel zoomPanel;

    public MainPanel () {
        super (new BorderLayout ());
        // --- Mouse Adapter ---
        MouseAdapter mouseAdapter = new MouseAdapter () {
            @Override public void mouseDragged (MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton (e)) imagePanel.setPixelColor (e.getX (), e.getY ());
            }
            /* @Override public void mouseMoved (MouseEvent e) {
                points.add (e.getPoint ());
            } */
            @Override public void mouseReleased (MouseEvent e) {
                // for (Point p : points) System.out.println (p);
                if (SwingUtilities.isLeftMouseButton (e)) imagePanel.setPixelColor (e.getX (), e.getY ());
            }
        };
        // --- Image Panel ---
        imagePanel = new ImagePanel ();
        imagePanel.addMouseMotionListener (mouseAdapter);
        imagePanel.addMouseListener (mouseAdapter);
        // --- Image Panel View ---
        JPanel imagePanelView = new JPanel (new FlowLayout (FlowLayout.LEFT, 20, 20));
        imagePanelView.add (imagePanel);
        // --- Image Panel Scroll Pane ---
        JScrollPane scrollPane = new JScrollPane (imagePanelView);
        scrollPane.addMouseWheelListener (new MouseWheelListener () {
            @Override public void mouseWheelMoved (MouseWheelEvent e) {
                if (e.isControlDown ()) {
                    int rotation = e.getWheelRotation ();
                    if ((rotation < 0 && imagePanel.zoomIn ()) || (rotation > 0 && imagePanel.zoomOut ())) zoomPanel.zoomLevelChanged ();
                }
            }
        });
        scrollPane.getHorizontalScrollBar ().setUnitIncrement (100);
        scrollPane.getVerticalScrollBar ().setUnitIncrement (100);
        scrollPane.setBorder (new EmptyBorder (0, 0, 0, 0));
        // --- Loading image ---
        try {
            imagePanel.setImage (ImageIO.read (new URL ("https://spotlight.it-notes.ru/wp-content/uploads/2016/10/255b4aa1455158ffde176a1e814c634f.jpg")));
        }
        catch (Exception e) {
            e.printStackTrace ();
        }
        // --- Bottom Panel ---
        JPanel bottomPanel = new JPanel (new BorderLayout (100, 0));
        bottomPanel.add (zoomPanel = new ZoomPanel (imagePanel), BorderLayout.EAST);
        bottomPanel.setBorder (new MatteBorder (1, 0, 0, 0, getBackground ().darker ()));
        // --- Adding components ---
        add (scrollPane, BorderLayout.CENTER);
        add (bottomPanel, BorderLayout.SOUTH);
    }
}
class ImagePanel extends JPanel
{
    private int zoomLevel;
    private BufferedImage image;
    private int rgb = Color.YELLOW.getRGB ();
    //private ArrayList <Point> drawnPoints;

    public ImagePanel () {
        super (new FlowLayout (FlowLayout.LEFT, 0, 0));
        zoomLevel = 1;
        //drawnPoints = new ArrayList <Point> ();
    }
    protected BufferedImage getImage () {
        if (image == null) return null;
        // A copy of original image is returned.
        BufferedImage copy = new BufferedImage (image.getWidth (), image.getHeight (), image.getType ());
        Graphics2D g = copy.createGraphics ();
        g.drawImage (image, 0, 0, null);
        g.dispose ();
        return copy;
    }
    protected int getImageHeight () {
        if (image == null) return 0;
        return image.getHeight ();
    }
    protected int getImageWidth () {
        if (image == null) return 0;
        return image.getWidth ();
    }
    @Override public Dimension getPreferredSize () {
        if (image == null) return new Dimension (0, 0);
        return new Dimension (image.getWidth () * zoomLevel, image.getHeight () * zoomLevel);
    }
    public int getZoomLevel () {
        return zoomLevel;
    }
    @Override protected void paintComponent (Graphics g) {
        super.paintComponent (g);
        g.drawImage (image, 0, 0, image.getWidth () * zoomLevel, image.getHeight () * zoomLevel, this);
        //if (drawnPoints != null) {
        //  g.setColor (Color.YELLOW);
        //  for (Point point : drawnPoints) g.fillRect (point.x * zoomLevel, point.y * zoomLevel, zoomLevel, zoomLevel);
        //}
    }
    private void refresh () {
        Container parent = getParent ();
        parent.revalidate ();
        parent.repaint ();
    }
    protected void setImage (BufferedImage image) {
        this.image = image;
        refresh ();
    }
    protected void setPixelColor (int scaledX, int scaledY) {
        int x = scaledX / zoomLevel, y = scaledY / zoomLevel;
        if (x >= 0 && y >= 0 && x < image.getWidth () && y < image.getHeight ()) {
            //drawnPoints.add (new Point (x, y));
            image.setRGB (x, y, rgb);
            refresh ();
        }
    }
    protected boolean zoom (int zoomLevel) {
        if (image == null || zoomLevel < 1 || zoomLevel > 8) return false;
        this.zoomLevel = zoomLevel;
        refresh ();
        return true;
    }
    protected boolean zoomIn () {
        return image != null && zoom (zoomLevel + 1);
    }
    protected boolean zoomOut () {
        return image != null && zoom (zoomLevel - 1);
    }
}
class ZoomPanel extends JPanel
{
    private ImagePanel imagePanel;
    private JLabel label;

    protected ZoomPanel (ImagePanel imagePanel) {
        super (new FlowLayout (FlowLayout.RIGHT, 20, 0));
        this.imagePanel = imagePanel;
        add (label = new JLabel ("100%"));
        add (new JButton (new AbstractAction ("-") {
            @Override public void actionPerformed (ActionEvent e) {
                if (imagePanel.zoomOut ()) zoomLevelChanged ();
            }
        }));
        add (new JButton (new AbstractAction ("+") {
            @Override public void actionPerformed (ActionEvent e) {
                if (imagePanel.zoomIn ()) zoomLevelChanged ();
            }
        }));
        setBorder (new EmptyBorder (3, 0, 3, 20));
    }
    protected void zoomLevelChanged () {
        label.setText (String.valueOf (imagePanel.getZoomLevel () * 100) + "%");
    }
}

And below there is a screenshot which shows the problem:

EDIT

Thanks to @ug_ and @MadProgrammer for their explanations and suggestions. I had already thought to use drawLine method, as i told in the original post, but i was not able to figure out how to solve the problems i stated above.

Now i realised that, if the image is zoomed, it is pretty simple to use drawLine on the original image by getting its graphics, and i don't need at all to keep a list of points to be drawned later, since i just have to keep the last point drawned (like @ug_ does in his code).

I edit my code, i just post the blocks which have been updated:

In MainPanel constructor:

MouseAdapter mouseAdapter = new MouseAdapter () {
            @Override public void mouseDragged (MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton (e)) imagePanel.addPoint (e.getX (), e.getY ());
            }
            @Override public void mouseReleased (MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton (e)) imagePanel.setPixelColor (e.getX (), e.getY ());
            }
        };

ImagePanel class:

class ImagePanel extends JPanel
{
    private int zoomLevel;
    private BufferedImage image;
    private int rgb = Color.YELLOW.getRGB ();
    private Point lastPoint;

    public ImagePanel () {
        super (new FlowLayout (FlowLayout.LEFT, 0, 0));
        zoomLevel = 1;
    }
    protected void addPoint (int scaledX, int scaledY) {
        int x = scaledX / zoomLevel, y = scaledY / zoomLevel;
        if (x >= 0 && y >= 0 && x < image.getWidth () && y < image.getHeight ()) {
            if (lastPoint == null) image.setRGB (x, y, rgb);
            else {
                Graphics2D g = image.createGraphics ();
                g.setColor (Color.YELLOW);
                g.drawLine (lastPoint.x, lastPoint.y, x, y);
                g.dispose ();
            }
            lastPoint = new Point (x, y);
            refresh ();
        }
    }
    protected int getImageHeight () {
        if (image == null) return 0;
        return image.getHeight ();
    }
    protected int getImageWidth () {
        if (image == null) return 0;
        return image.getWidth ();
    }
    @Override public Dimension getPreferredSize () {
        if (image == null) return new Dimension (0, 0);
        return new Dimension (image.getWidth () * zoomLevel, image.getHeight () * zoomLevel);
    }
    public int getZoomLevel () {
        return zoomLevel;
    }
    @Override protected void paintComponent (Graphics g) {
        super.paintComponent (g);
        g.drawImage (image, 0, 0, image.getWidth () * zoomLevel, image.getHeight () * zoomLevel, this);
    }
    private void refresh () {
        Container parent = getParent ();
        parent.revalidate ();
        parent.repaint ();
    }
    protected void setImage (BufferedImage image) {
        this.image = image;
        refresh ();
    }
    protected void setPixelColor (int scaledX, int scaledY) {
        int x = scaledX / zoomLevel, y = scaledY / zoomLevel;
        if (x >= 0 && y >= 0 && x < image.getWidth () && y < image.getHeight ()) {
            lastPoint = null;
            image.setRGB (x, y, rgb);
            refresh ();
        }
    }
    protected boolean zoom (int zoomLevel) {
        if (image == null || zoomLevel < 1 || zoomLevel > 8) return false;
        this.zoomLevel = zoomLevel;
        refresh ();
        return true;
    }
    protected boolean zoomIn () {
        return image != null && zoom (zoomLevel + 1);
    }
    protected boolean zoomOut () {
        return image != null && zoom (zoomLevel - 1);
    }
}

Now it works pretty fine!

解决方案

Your not going to get a mouse event for every pixel your mouse moves over, this is especially true if you move it really fast. I tried to find some good documentation referring to why this is but couldn't off hand. You might find something in https://docs.oracle.com/javase/8/docs/api/java/awt/event/MouseEvent.html tho.

What I would do to solve this issue is use the methods provided by the java.awt.Graphics method to draw a line from your previous position to your new one. Do this onto either your image or a layer of some sort. Heres some code that does just that:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

public class SO46085131 extends JPanel {

    private final Dimension LAYER_SIZE = new Dimension(300, 300);

    private Point prevPoint = null;
    private BufferedImage paintLayer;
    private Graphics paintLayerGraphics;

    public SO46085131(){
        setBackground(Color.black);
        // create our layer that we will paint onto
        paintLayer = new BufferedImage(LAYER_SIZE.width, LAYER_SIZE.height, BufferedImage.TYPE_INT_ARGB);

        // get our graphics for the painting layer and fill in a background cause thats cool
        paintLayerGraphics = paintLayer.getGraphics();
        paintLayerGraphics.setColor(Color.red);
        paintLayerGraphics.fillRect(0, 0, paintLayer.getWidth(), paintLayer.getHeight());

        setBackground(Color.WHITE);
        // listen for drag events, then draw
        // TODO: You should listen for mouse up and down events instead of dragging so you can clear your previous point
        // TODO: Big boy bugs here! for you to fix
        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // if we moved the mouse previously draw a line from our prev point to our current position
                if(prevPoint != null) {
                    paintLayerGraphics.setColor(Color.black);
                    paintLayerGraphics.drawLine(prevPoint.x, prevPoint.y, e.getX(), e.getY());
                    repaint();
                }
                // store previous point
                prevPoint = e.getPoint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        // draw our sweet painting layer ontop of our component.
        g.drawImage(paintLayer, 0, 0, this);
    }

    public static void main(String [] args) {
        // just new up a sample jframe to display our stuff on 
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SO46085131());
        frame.setSize(500, 400);
        frame.setVisible(true);
    }
}

这篇关于正确绘制图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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