2017-11-03 4 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ミリ秒ごとにタイマーをリセット?

したがって、簡単な答えは、JSliderChangeListenerを使用して、スライダの値がいつ変化するかを判断することです。私は

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

    } 
} 
関連する問題