簡體   English   中英

Java Swing繪圖應用程序未繪圖

[英]Java Swing drawing app not drawing

我目前正在使用Java Swing庫編寫一個簡單的繪畫應用程序。 一切似乎都運行良好-mousePressed和mouseDragged都被調用了-但是程序沒有在繪圖板上畫任何東西。 如果有人能告訴我為什么這里什么都沒畫,我會很高興。

碼:

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

public class PaintGUI extends JComponent {

    private static final long serialVersionUID = 1L;

    JButton red, green, blue, clear;
    Image img;
    Graphics2D gfx;
    JFrame drawFrame;
    JPanel drawPan;
    Container cont;
    MyListener ml;
    Action act;
    int x, y, prevX, prevY;

    public PaintGUI(){
        //Initialisering av panel, frame og content
        drawFrame = new JFrame("IFIPaint");
        drawPan = new JPanel();
        cont = drawFrame.getContentPane();
        cont.setLayout(new BorderLayout());
        cont.add(BorderLayout.SOUTH, drawPan);

        //Setter størrelser
        drawPan.setPreferredSize(new Dimension(30, 60));
        drawPan.setMinimumSize(new Dimension(30, 60));
        drawPan.setMaximumSize(new Dimension(30, 60));

        //Ordner knappene
        red = new JButton("Rød");
        green = new JButton("Grønn");
        blue = new JButton("Blå");
        clear = new JButton("Slett alt");

        //Putter knappene på panelet
        drawPan.add(red);
        drawPan.add(green);
        drawPan.add(blue);
        drawPan.add(clear);

        //Legger på action listeners
        act = new Action();
        red.addActionListener(act);
        green.addActionListener(act);
        blue.addActionListener(act);
        clear.addActionListener(act);

        //Fullfører vindu og setter synlighet
        drawPan.setVisible(true);
        drawFrame.setSize(500, 500);
        drawFrame.setVisible(true);
        drawFrame.add(this);
        this.setSize(500, 500);
        this.paintComponent(gfx);
        this.setVisible(true);

        drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        draw();
    }

    public void draw() {
        ml = new MyListener();
        this.addMouseListener(ml);
        this.addMouseMotionListener(ml);
    }

    public void paintComponent(Graphics g) {

        if (img == null) {
            img = createImage(drawFrame.getWidth(),drawFrame.getHeight());

            gfx = (Graphics2D) img.getGraphics();

            gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            gfx.setPaint(Color.WHITE);
            gfx.fillRect(0, 0, this.getSize().width, this.getSize().height);
            gfx.setPaint(Color.RED);
            repaint();
        }

        gfx.drawImage(img, 0, 0, null);
    }


    class Action implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            if(e.getSource() == red){
                gfx.setPaint(Color.RED);
                repaint();
            } else if (e.getSource() == green){
                gfx.setPaint(Color.GREEN);
                repaint();
            } else if (e.getSource() == blue) {
                gfx.setPaint(Color.BLUE);
                repaint();
            } else if (e.getSource() == clear) {
                gfx.clearRect(0, 0, drawFrame.getWidth(), drawFrame.getHeight());
                repaint();
            }
        }

    }

    class MyListener extends MouseAdapter {

        public void mousePressed(MouseEvent e) {
            prevX = e.getX();
            prevY = e.getY();
        }

        public void mouseDragged(MouseEvent e) {
            x = e.getX();
            y = e.getY();
            gfx.drawLine(prevX, prevY, x, y);
            repaint();
            prevX = x;
            prevY = y;

        }
    }

}

不要在任何繪制方法中直接或間接調用repaint ,這樣做會導致將新的繪制事件一遍又一遍地調度到事件隊列中,從而快速消耗您的CPU。

您實際上並沒有在屏幕設備上繪畫,為此,您需要在提供的Graphics上下文上繪畫。

protected void paintComponent(Graphics g) {

    if (img == null) {
        img = createImage(drawFrame.getWidth(),drawFrame.getHeight());

        gfx = (Graphics2D) img.getGraphics();

        gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        gfx.setPaint(Color.WHITE);
        gfx.fillRect(0, 0, this.getSize().width, this.getSize().height);
        gfx.setPaint(Color.RED);
        // If you create it you should dispose of it...
        gfx.dispose();
    }

    g.drawImage(img, 0, 0, this);
}

因為默認情況下,使用JComponent是透明的,所以調用super.paintComponent甚至更為重要,如果不這樣做,最終將導致各種討厭的繪畫工件

在相同的繪圖表面上添加組件的事實意味着您可能會掩蓋正在繪制的內容。 請記住,並非所有組件都是透明的,默認情況下, JPanel是不透明的。

更好的解決方案是創建一個專用的繪圖面板,該面板除了按您想要的方式繪制所需內容外,什么也不做。 然后將其與控件一起添加到另一個容器中。 然后,您將使用設置器來更改繪畫的發生方式,例如使用顏色

您似乎正在嘗試做雙緩沖方法。 將緩沖區的繪制與組件的繪制分開可能會更容易,這將允許您以所需的任何方式修改緩沖區,然后調用repaint,該操作只會將圖像繪制到組件Graphics上下文

首先,在paint component方法中調用super。

之所以沒有繪制任何圖像,是因為使用此代碼,您僅在當前沒有圖像時才更新要繪制的圖像。 我將paintComponent方法更改為如下所示:

public void paintComponent(Graphics g) {

    super.paintComponent(g);

    img = createImage(drawFrame.getWidth(),drawFrame.getHeight());
    gfx = (Graphics2D) img.getGraphics();
    gfx.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
    gfx.setPaint(Color.WHITE);
    gfx.fillRect(0, 0, this.getSize().width, this.getSize().height);
    gfx.setPaint(Color.RED);

    gfx.drawImage(img, 0, 0, null);
}

似乎drawPan妨礙了您查看圖像。

刪除其創建並將其添加到內容窗格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM