2014-07-24 66 views
-1

我的程序是将字母转换为一些信号。我的主要方法会生成一些随机字母。该信件被传递给另一个方法,该方法根据生成的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); 

    } 
} 
+0

使用逻辑和一致的代码格式风格!代码缩进旨在帮助人们遵循程序流程。 –

回答

3

两件事情......

首先,调用事件分派线程中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框架,是单线程的,而不是线程安全的。

这意味着,您不能阻止GUI线程,这样做会阻止UI被重新绘制等等,并且您必须在GUI线程的上下文内更新任何UI组件的状态。

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

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; 
     } 

    } 

} 
+0

Swing是一个单线程框架,这意味着如果你阻塞事件分派线程(主UI线程),它将无法绘制或响应用户输入。请参见[并发中的Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) – MadProgrammer

+0

我在paint方法内部添加了睡眠线程。我仍然没有得到预期的结果。和案例A一样,它应该闪烁三次。对于案例B,它应该闪烁两次,依此类推。有什么办法可以实现它吗?请帮助。 – user3857726

+0

Swing是一个单线程环境。任何阻塞Swing线程的东西(如'Thread.sleep')都会停止绘画的发生。 – MadProgrammer

相关问题