通过单击JButton绘制形状

时间:2013-05-17 07:30:41

标签: java swing jbutton paint jcomponent

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

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

如果我把代码放在构造函数内的方法“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);
        }
    }
}
}

1 个答案:

答案 0 :(得分: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();}
}

在美国东部时间。除了每80毫秒向UI添加多个新组件之外,您还要阻止负责更新屏幕的线程......

查看Concurrency in Swing了解详情。

此类型的动画应由javax.swing.Timer处理。

自定义绘画应作为一般规则在paintComponent方法中执行。你也应该首先打电话给super.paintXxx。在后台需要处理很多工作,特别是如果组件是透明的。

查看Performing Custom PaintingPainting in AWT and 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支持的一部分...或任何类型的幻数