在满足某些条件时画一个圆圈

时间:2014-07-24 05:24:30

标签: java swing graphics awt frame

我的程序是将字母转换为某些信号。我的主要方法是生成一些随机字母。该字母被传递给另一个方法,该方法根据生成的Letter调用repaint()方法.PaintComponent()方法用于绘制一个填充白色的圆。当我执行程序时,我只得到一个Jframe。我没有看到圆圈。请帮助。

package morsecode;

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import java.awt.*;


public class MorseCode extends Frame {


    public static void main(String[] args) {

                MorseCode mc = new MorseCode();
                 MorseCode frame = new MorseCode();


        final String chars = "abcdefghijklmnopqrstuvwxyz1234567890";
        char word;

                for(int i=1;i<=1;i++)

                {
            Random rand = new Random();
            int x = rand.nextInt(36);
            word = chars.charAt(x);
            System.out.print(word);
                        frame.setBackground(Color.BLACK);
                        frame.addWindowListener(
      new WindowAdapter()
      {
         @Override
         public void windowClosing(WindowEvent we)
         {
            System.exit(0);
         }
      }
      );

      frame.setSize(400, 400);
      frame.setVisible(true);
                         mc.toMorseCode(word);
                }
    }


    void toMorseCode(char letter)
    {

    switch(letter)
    {
        case 'A' | 'a':
            repaint();
            Thread.sleep(1000);
            repaint();
            Thread.sleep(2000);
            break;
        case 'B' | 'b':
            repaint();
            Thread.sleep(1000);
             repaint();
              Thread.sleep(1000);
              repaint();
                Thread.sleep(1000);
             repaint();
             Thread.sleep(2000);
            break; ..............
       }
}
    public void paintComponent(Graphics g) {
     Graphics2D ga = (Graphics2D)g;
     ga.setColor(Color.white);
     ga.fillOval(125,125,150,150);

  }
}

1 个答案:

答案 0 :(得分:3)

两件事......

首先,在Event Dispatching Thread中调用Thread.sleep(2000);将阻止EDT处理事件队列上的事件,包括绘制事件。

其次,Frame没有paintComponent

添加@Override注释并尝试调用super.paintComponent会突出显示此问题,因为代码无法编译。

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

首先,首先使用JPanel来保存核心逻辑并执行自定义绘画。

其次,使用javax.swing.Timer执行动画。有关详细信息,请参阅How to use Swing Timers

<强>更新

基本概念相对简单。您需要某种第二/后台线程,它可以在输出中产生更改之间的延迟。然后,您需要在每次延迟之前根据您尝试显示的信息类型更新UI。

实现变得棘手,因为与大多数GUI框架一样,Swing是单线程的而不是线程安全的。

这意味着,您无法阻止GUI线程,这样做会阻止UI重新绘制,除此之外,还必须在GUI线程的上下文中更新任何UI组件的状态。

这意味着虽然您可以使用Thread在后​​台运行,但您必须确保对UI的所有更改/修改仅在EDT内执行。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class MorseCodeTest {

    public static void main(String[] args) {
        new MorseCodeTest();
    }

    public MorseCodeTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static final int GAP = 500;
    public static final int DOT = 1000;
    public static final int DASH = 4000;

    public interface Transmitter {

        public void setTap(boolean tap);

    }

    public class TestPane extends JPanel implements Transmitter {

        private MorseCode code;
        private boolean tapped;

        public TestPane() {

            code = MorseCode.create('A').addDot().addDash();

            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    Signalar signalar = new Signalar(TestPane.this, code);
                    signalar.execute();
                }

            });

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (tapped) {
                Graphics2D g2d = (Graphics2D) g.create();
                int diameter = Math.min(getWidth(), getHeight()) / 2;
                int x = (getWidth() - diameter) / 2;
                int y = (getHeight() - diameter) / 2;
                g2d.fillOval(x, y, diameter, diameter);
                g2d.dispose();
            }
        }

        @Override
        public void setTap(boolean tap) {
            tapped = tap;
            repaint();
        }

    }

    public class Signalar extends SwingWorker<Void, Boolean> {

        private final MorseCode code;
        private final Transmitter transmitter;

        public Signalar(Transmitter transmitter, MorseCode code) {
            this.code = code;
            this.transmitter = transmitter;
        }

        @Override
        protected void process(List<Boolean> chunks) {
            transmitter.setTap(chunks.get(chunks.size() - 1));
        }

        @Override
        protected Void doInBackground() throws Exception {
            for (Tone tone : code.getTones()) {
                publish(true);
                Thread.sleep(tone.getDelay());
                publish(false);
                Thread.sleep(GAP);
            }
            return null;
        }

    }

    public static class Tone {

        private final int delay;

        public Tone(int delay) {
            this.delay = delay;
        }

        public int getDelay() {
            return delay;
        }

    }

    public static class DashTone extends Tone {

        public DashTone() {
            super(DASH);
        }

    }

    public static class DotTone extends Tone {

        public DotTone() {
            super(DOT);
        }

    }

    public static class MorseCode {

        private final char value;
        private final List<Tone> tones;

        public static MorseCode create(char value) {
            MorseCode code = new MorseCode(value);
            return code;
        }

        public MorseCode(char value) {
            this.value = value;
            this.tones = new ArrayList<>(25);
        }

        public char getValue() {
            return value;
        }

        public MorseCode addDash() {
            return addTone(new DashTone());
        }

        public MorseCode addDot() {
            return addTone(new DotTone());
        }

        public MorseCode addTone(Tone tone) {
            tones.add(tone);
            return this;
        }

        public Iterable<Tone> getTones() {
            return tones;
        }

    }

}