2017-11-03 22 views
-4

스윙에서는 창을 만들고 사용자가 입력 한 BPM (Beats per minute)에 따라 화면에 글자가 깜박 거리기를 원합니다. 정확하게 깜박이는 타이밍에 대해 궁금해하고있었습니다. 스윙 타이머를 사용해 보았지만 그다지 정확하지 않아 일시 중지 또는 지연이 많이 발생합니다. System.nanoTime()System.currentTimeMillis()을 사용하는 것에 대해 들었지만 타이머를 만들기 위해 타이머를 구현하는 방법을 알지 못했습니다. 어떤 도움을 주시면 감사하겠습니다!Java에서 사용자가 제공하는 BPM 값에 따라 화면에서 문자를 플래시로 만들 수 있습니까?

Note.java

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import javax.swing.JButton; 
import java.awt.event.*; 
import java.awt.*; 

public class Note extends JFrame implements ActionListener { 

JPanel mainScreen = new JPanel(); 
JPanel south = new JPanel(); 
JPanel north = new JPanel(); 

//emptyNumberMain = how many empty panels you want to use 
public int emptyNumberMain = 2; 
JPanel[] emptyMain = new JPanel[emptyNumberMain]; 

JLabel title = new JLabel("Fretboard Trainer!"); 
JButton start = new JButton("Start!"); 

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

public Note() { 
    super("Random Note!"); 
    setSize(300,300); 
    setResizable(false); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 

    //creates emptyNumberMain amount of empty panels 
    for (int i = 0; i < emptyNumberMain; i++) { 
     emptyMain[i] = new JPanel(); 
    } 


    mainScreen.setLayout(new BorderLayout()); 

    south.setLayout(new GridLayout(1,1)); 
    south.add(emptyMain[0]); 
    south.add(start); 
    south.add(emptyMain[1]); 

    north.setLayout(new GridLayout(1,2)); 
    north.add(title); 

    title.setHorizontalAlignment(JLabel.CENTER); 
    title.setFont(title.getFont().deriveFont(32f)); 
    start.addActionListener(this); 

    mainScreen.add(north, BorderLayout.NORTH); 
    mainScreen.add(south, BorderLayout.SOUTH); 
    add(mainScreen); 
    setVisible(true); 
} 

public void actionPerformed(ActionEvent e) { 
    if (e.getSource() == start) { 
     dispose(); 
     new RandomNote(); 
    } 
} 
} 

RandomNote.java

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 
import java.util.Random; 
import javax.swing.Timer; 
import javax.swing.JSlider; 
import java.awt.event.*; 
import java.awt.*; 

public class RandomNote extends JFrame { 

    JPanel noteScreen = new JPanel(); 
    JPanel center = new JPanel(); 
    JPanel southSlider = new JPanel(); 
    JLabel bpm = new JLabel(); 
    //emptyNumber = how many empty panels you want to use 
    int emptyNumber = 2; 
    JPanel[] empty = new JPanel[emptyNumber]; 

    JLabel rndNote = new JLabel(); 
    JSlider slider = new JSlider(0,200,100); 

    Timer timer2 = new Timer(100, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      bpm.setText(Integer.toString(slider.getValue())); 
      timer.setDelay((int) ((60.0/slider.getValue()) * 1000)); 
     } 
    }); 
    public RandomNote() { 
     super("Random Notes!"); 
     timer.start(); 
     timer2.start(); 
     setSize(500,500); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setResizable(false); 

     //creates variable emptyNumber amount of empty panels 
     for (int i = 0; i < emptyNumber; i++) { 
      empty[i] = new JPanel(); 
     } 

     noteScreen.setLayout(new BorderLayout()); 

     center.setLayout(new GridLayout(1,1)); 
     center.add(rndNote); 

     southSlider.setLayout(new GridLayout(3,1)); 
     slider.setLabelTable(slider.createStandardLabels(20)); 
     slider.setPaintTicks(true); 
     slider.setPaintLabels(true); 
     slider.setMinorTickSpacing(5); 
     slider.setMajorTickSpacing(20); 
     southSlider.add(slider); 
     southSlider.add(bpm); 

     rndNote.setHorizontalAlignment(JLabel.CENTER); 
     rndNote.setFont(rndNote.getFont().deriveFont(32f)); 


     noteScreen.add(center, BorderLayout.CENTER); 
     noteScreen.add(southSlider, BorderLayout.SOUTH); 
     add(noteScreen); 
     setVisible(true); 
    } 

    Timer timer = new Timer(1000, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      rndNote.setText(noteOutput()); 
     } 
    }); 

    public static String noteOutput() { 
     Random rand = new Random(); 
     String[] note = {"A", "B", "C", "D", "E", "F", "G"}; 
     int randNum = rand.nextInt(7); 
     return note[randNum]; 
    } 
} 
+1

실행 가능한 예제로 코드를 알려주세요 ... 자세한 내용

실행 가능한 개념으로

에 대한 How to Use Sliders를 살펴 가진 권하고 싶습니다 ([SSCCE] (http://sscce.org)), 우리는 또한 무엇이 잘못되었는지를 볼 수 있습니다. –

+1

http://idownvotedbecau.se/noattempt/ – lexicore

+0

@lexicore - 해당 링크 저장 중. 감사. –

답변

1

나를 밖으로 점프 즉각적인 것은 이것입니다 ... 당신이 업데이트해야 할 이유

Timer timer2 = new Timer(100, new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     bpm.setText(Integer.toString(slider.getValue())); 
     timer.setDelay((int) ((60.0/slider.getValue()) * 1000)); 
    } 
}); 

텍스트 및 100 밀리 초마다 타이머를 재설정?

따라서 간단한 대답은 JSlider에서 ChangeListener을 사용하여 슬라이더의 값이 변경되는시기를 결정하는 것입니다. 내가

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.Icon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

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

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

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

    public class TestPane extends JPanel { 

     private AnimatableLabel label; 

     public TestPane() { 
      setLayout(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 
      label = new AnimatableLabel("BMP"); 
      label.setHorizontalAlignment(JLabel.CENTER); 
      add(label, gbc); 
      label.start(); 

      JSlider slider = new JSlider(10, 200); 
      slider.addChangeListener(new ChangeListener() { 
       @Override 
       public void stateChanged(ChangeEvent e) { 
        label.setBPM(slider.getValue()); 
       } 
      }); 
      slider.setValue(60); 

      add(slider, gbc); 
     } 

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

    } 

    public class AnimatableLabel extends JLabel { 

     private Timer pulseTimer; 
     private Timer fadeTimer; 

     private double bpm = 60; 
     private double alpha = 0; 
     private Long pulsedAt; 

     public AnimatableLabel(String text, Icon icon, int horizontalAlignment) { 
      super(text, icon, horizontalAlignment); 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public AnimatableLabel(String text, int horizontalAlignment) { 
      super(text, horizontalAlignment); 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public AnimatableLabel(String text) { 
      super(text); 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public AnimatableLabel(Icon image, int horizontalAlignment) { 
      super(image, horizontalAlignment); 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public AnimatableLabel(Icon image) { 
      super(image); 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public AnimatableLabel() { 
      setBackground(Color.RED); 
      initTimer(); 
     } 

     public void start() { 
      updateTimer(); 
     } 

     public void stop() { 
      pulseTimer.stop(); 
      fadeTimer.stop(); 
     } 

     protected void initTimer() { 
      pulseTimer = new Timer((int)(getDuration()), new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        pulsedAt = System.currentTimeMillis(); 
        alpha = 1.0; 
        repaint(); 
       } 
      }); 
      pulseTimer.setInitialDelay(0); 
      pulseTimer.setCoalesce(true); 

      fadeTimer = new Timer(5, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (pulsedAt == null) { 
         return; 
        } 

        long fadingDuration = System.currentTimeMillis() - pulsedAt;     
        alpha = 1.0 - (fadingDuration/getDuration()); 
        if (alpha > 1.0) { 
         alpha = 1.0; 
        } else if (alpha < 0.0) { 
         alpha = 0.0; 
        } 
        repaint(); 
       } 
      }); 
      fadeTimer.setCoalesce(true); 
     } 

     protected double getDuration() { 
      return (60.0/bpm) * 1000.0; 
     } 

     protected void updateTimer() { 
      fadeTimer.stop(); 
      pulseTimer.stop(); 
      pulseTimer.setDelay((int)getDuration()); 

      pulseTimer.start(); 
      fadeTimer.start(); 
     } 

     public void setBPM(double bpm) { 
      this.bpm = bpm; 
      setText(Double.toString(bpm)); 
      updateTimer(); 
     } 

     public double getBPM() { 
      return bpm; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setComposite(AlphaComposite.SrcOver.derive((float)alpha)); 
      g2d.setColor(Color.RED); 
      g2d.fillRect(0, 0, getWidth(), getHeight()); 
      g2d.dispose(); 
      super.paintComponent(g); 
     } 

    } 
}