1

我目前正在尝试通过单击按钮来绘制图形。当我单击按钮并且它没有显示在面板中时会出现我的问题,但我知道它正在绘制,因为它通过循环运行。

当我请求面板在构造函数内部而不是按钮内部,在构造函数内部绘制它时,绘制将发生

如果我将代码放在构造函数内的方法“stuff()”中,它将绘制一切都很好。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainFrame{
    public static void main(String[]args){
        MainFrame f = new MainFrame();
    }
public JFrame frame = new JFrame();
public JPanel panel = new JPanel(new BorderLayout());
public MainFrame(){
    JButton button1 = new JButton("Shweet Button");
    button1.setBounds(185, 10, 130, 20);
    frame.setBounds(1680/4,1050/4,500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(panel);
    panel.setBackground(Color.black);
    frame.setVisible(true);
    frame.getContentPane().setLayout(null);
    frame.add(button1);
    button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            stuff();
        }
    });
}
public void stuff(){
    for(int i = 0;i<1000;i++){
        panel.add(new paintComponent());
        panel.setBackground(Color.black);
        frame.repaint();
        try {
            Thread.sleep(80);
        } catch (InterruptedException e1){e1.printStackTrace();}
    }
}
static class paintComponent extends JComponent{
    public int options;
    public void paint(Graphics g){
        Graphics2D g2 = (Graphics2D)g;
        g2.setColor(Color.white);

        if(options == 0){
            options = 1;
            g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50);
            g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30);
            g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220);
            g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+160);
            g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210);
            g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260);
            g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260);
        }else if(options == 1){
            options = 0;
            g2.drawOval(50, (JFrame.HEIGHT/2)+100, 50, 50);
            g2.drawOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.fillOval(60, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.drawOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.fillOval(80, (JFrame.HEIGHT/2)+110, 8, 8);
            g2.drawArc(65, (JFrame.HEIGHT/2)+130, 100, 0, 140, 30);
            g2.drawLine(75, (JFrame.HEIGHT/2)+150, 75, (JFrame.HEIGHT/2)+220);
            g2.drawLine(75, (JFrame.HEIGHT/2)+180, 100, (JFrame.HEIGHT/2)+180);
            g2.drawLine(75, (JFrame.HEIGHT/2)+180, 65, (JFrame.HEIGHT/2)+210);
            g2.drawLine(75, (JFrame.HEIGHT/2)+220, 50, (JFrame.HEIGHT/2)+260);
            g2.drawLine(75, (JFrame.HEIGHT/2)+220, 100, (JFrame.HEIGHT/2)+260);
        }
    }
}
}
4

1 回答 1

3

您正在阻塞事件调度线程,该线程除其他外负责处理绘制请求。

你永远不应该做这样的事情......

for(int i = 0;i<1000;i++){
    panel.add(new paintComponent());
    panel.setBackground(Color.black);
    frame.repaint();
    try {
        Thread.sleep(80);
    } catch (InterruptedException e1){e1.printStackTrace();}
}

在 EDT 内。除了每 80 毫秒向 UI 添加多个新组件这一事实之外,您还阻塞了负责更新屏幕的线程......

查看Swing 中的并发以获取更多详细信息。

这种类型的动画应该由javax.swing.Timer.

paintComponent作为一般规则,应在该方法中执行自定义绘画。当然,您也应该先打电话super.paintXxx。在后台有很多工作需要处理,尤其是在组件是透明的情况下。

查看在 AWT 和 Swing中执行自定义绘画和绘画以获取更多详细信息。

保存您的理智并学习如何使用布局管理器,从长远来看,它们将使您的生活更轻松。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MainFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                MainFrame f = new MainFrame();
            }
        });
    }
    public JFrame frame = new JFrame();
    public JPanel panel = new JPanel(new BorderLayout());
    private WavePane waver;

    public MainFrame() {
        waver = new WavePane();
        JButton button1 = new JButton("Shweet Button");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        panel.setBackground(Color.black);
        frame.add(button1, BorderLayout.SOUTH);
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                stuff();
            }
        });
        panel.add(waver);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public void stuff() {
//        for (int i = 0; i < 1000; i++) {
//            panel.add(new paintComponent());
//            panel.setBackground(Color.black);
//            frame.repaint();
//            try {
//                Thread.sleep(80);
//            } catch (InterruptedException e1) {
//                e1.printStackTrace();
//            }
//        }
        waver.walk(!waver.isWaving());
    }

    public class WavePane extends JComponent {

        private int options;
        private Timer timer;

        public WavePane() {
            setOpaque(false);
            timer = new Timer(80, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("tick");
                    options++;
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        public void walk(boolean walk) {
            if (walk) {
                timer.start();
            } else {
                timer.stop();
            }
        }

        public boolean isWaving() {
            return timer.isRunning();
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.white);

            int height = getHeight();

            if (options % 2 == 0) {
                g2.drawOval(50, 100, 50, 50);
                g2.drawOval(60, 110, 8, 8);
                g2.fillOval(60, 110, 8, 8);
                g2.drawOval(80, 110, 8, 8);
                g2.fillOval(80, 110, 8, 8);
                g2.drawArc(65, 130, 100, 0, 140, 30);
                g2.drawLine(75, 150, 75, 220);
                g2.drawLine(75, 180, 100, 160);
                g2.drawLine(75, 180, 65, 210);
                g2.drawLine(75, 220, 50, 260);
                g2.drawLine(75, 220, 100, 260);
            } else {
                g2.drawOval(50, 100, 50, 50);
                g2.drawOval(60, 110, 8, 8);
                g2.fillOval(60, 110, 8, 8);
                g2.drawOval(80, 110, 8, 8);
                g2.fillOval(80, 110, 8, 8);
                g2.drawArc(65, 130, 100, 0, 140, 30);
                g2.drawLine(75, 150, 75, 220);
                g2.drawLine(75, 180, 100, 180);
                g2.drawLine(75, 180, 65, 210);
                g2.drawLine(75, 220, 50, 260);
                g2.drawLine(75, 220, 100, 260);
            }
        }
    }
}

你不应该使用JFrame.HEIGHT它实际上与框架高度无关,但它是ImageObserver支持的一部分......或任何类型的幻数

于 2013-05-17T07:47:58.517 回答