Javaのタイマープログラムの時間について

このQ&Aのポイント
  • Javaのタイマープログラムについて、起動時間と実際のタイマー時間の違いがあります。
  • タイマーの起動時間を1msに設定しており、1000回タイマーを起動することで、トータルのタイマー時間を1秒と考えています。
  • しかし、実際のタイマー時間は20秒ほどかかってしまいます。コメントをいただけると助かります。
回答を見る
  • ベストアンサー

javaのタイマープログラムの時間について

下記のjavaのプログラムは、タイマー動作の確認プログラムです。 タイマーの起動時間を1msにし、1000回タイマーを起動しており トータルのタイマー時間は1秒と考えましたが、実際のタイマー時間は 20秒くらいかかります。 この件に関しまして、コメント頂けますと大変助かります。 import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.Timer; public class TimerTest1 extends JFrame implements ActionListener{ Timer timer; JLabel label; int sec; public static void main(String[] args){ TimerTest1 frame = new TimerTest1(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10, 300, 200); frame.setTitle("タイトル"); frame.setVisible(true); } TimerTest1(){ sec = 0; label = new JLabel(); JPanel labelPanel = new JPanel(); labelPanel.add(label); timer = new Timer(1, this); getContentPane().add(labelPanel, BorderLayout.CENTER); timer.start(); } public void actionPerformed(ActionEvent e){ label.setText(sec + " sec"); if (sec >= 1000){ timer.stop(); label.setText(" timer_stop"); }else{ sec++; } } } 以上、宜しくお願いします。

  • Java
  • 回答数1
  • ありがとう数0

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

Java の Timer 仕様は「指定された時間『以上』経過したことを保証する」だけで実際に 1ms の精度で正確にタスクが起動されることはほぼありません。実際 Swing のタイマーは Swing のバックグラウンド処理の影響で遅れを受けます。また、タイマーから呼び出された actionPerformed() の処理に 1ms 以上かかると次回のタスク起動が遅れます。それらの遅れが積み重なって20秒という時間がかかっていると思われます。 Java 標準の Timer は 1ms 精度が求められる処理を想定しておらず、本当にその精度が必要であれば Java RTS のような組込系のリアルタイム処理技術が必要になります。 ただ、実際にはそのような精度が求められる処理はまれで、例えば簡単なアニメーションであれば「16ms (約60fps) のタイマーを使用し、起動ごとに前回の起動からの時間 (16+アルファms) を計算してその分だけアニメーションを進める」といった方法で体感的に問題ないように実装します。

bakabon_X
質問者

補足

koiroha さま 早速の回答有難うございます。 使用者側とすれば、私が今回提示した程度のプログラムでは、1msは達成できなくても 2,3ms程度で割込みを実行できないかと考えています。 精度は全く必要ありません、つまりあるときは0.5msで動作し、次は3msで動作する、そして 偶には10msで操作するという具合でかまいません。 Timerの選択が間違っていたのかも知れませんね? いずれにせよ、回答有難うございました。

関連するQ&A

  • javaでスタート画面を作っていて困っています。

    現在javaでゲームのスタート画面を作っているのですが、パネルが透過されずに困っています。 プログラムソースは import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.ImageIcon; import java.awt.Container; import java.awt.BorderLayout; import javax.swing.*; import java.awt.Font; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.*; import java.awt.event.*; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.ImageIcon; import java.awt.Container; import java.awt.BorderLayout; import javax.swing.border.LineBorder; import javax.swing.border.EtchedBorder; import java.awt.Color; import java.awt.Container; class Start最新版 extends JFrame{ public static void main(String args[]){ Start最新版 frame = new Start最新版("タイトル"); frame.setVisible(true); } Start最新版(String title){ setTitle(title); setBounds(10, 10, 1024, 768); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel p = new JPanel(); p.setOpaque( false ); ImageIcon icon1 = new ImageIcon("Start.jpg"); JLabel label1 = new JLabel(icon1); JLabel label2 = new JLabel(); p.add(label1); Container contentPane = getContentPane(); contentPane.add(p, BorderLayout.CENTER); JButton button1 = new JButton("ゲームを始める"); button1.setFont(new Font("Mairyo", Font.PLAIN, 30)); JPanel n = new JPanel(); n.setOpaque(false); n.setLayout(new BoxLayout(n, BoxLayout.Y_AXIS)); n.add(Box.createRigidArea(new Dimension(290,30))); n.add(button1); となっています。「ゲームを始める」ボタンだけを残して、周りのパネルを透過して画像を表示させたいのですが、うまくいきません!解決方法をご存知の方どうか教えていただきたいです!よろしくお願いします。

  • JAVAでの背景画像表示

    現在javaでゲームのメニュー画面を作っているのですが、ボタンを配置する所まではできたんですが、背景に画像を表示することができなくて困っています! import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JLabel; import javax.swing.ImageIcon; import java.awt.Container; import java.awt.BorderLayout; import javax.swing.border.LineBorder; import javax.swing.border.EtchedBorder; import java.awt.Color; import java.awt.Container; public class Mati extends JFrame{ public static void main(String[] args){ Mati frame = new Mati(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(10, 10,650,650); frame.setTitle("街"); frame.setVisible(true); JPanel h = new JPanel(); h.setOpaque(false); ImageIcon icon1 = new ImageIcon("Mati.jpg"); JLabel label1 = new JLabel(icon1); JLabel label2 = new JLabel(); h.add(label1); } Mati(){ JButton button1 = new JButton("宿屋"); button1.setFont(new Font("Mairyo", Font.PLAIN, 30)); JButton button2 = new JButton("道具屋"); button2.setFont(new Font("Mairyo", Font.PLAIN, 30)); JButton button3 = new JButton("武器屋"); button3.setFont(new Font("Mairyo", Font.PLAIN, 30)); JButton button4 = new JButton("街を出る"); button4.setFont(new Font("Mairyo", Font.PLAIN, 30)); JPanel p = new JPanel(); p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(Box.createRigidArea(new Dimension(10,30))); p.add(button1); p.add(Box.createRigidArea(new Dimension(5,8))); p.add(button2); p.add(Box.createRigidArea(new Dimension(5,8))); p.add(button3); p.add(Box.createRigidArea(new Dimension(5,8))); p.add(button4); getContentPane().add(p, BorderLayout.CENTER); } } ソースはこのようになっています。これからどうすれば背景画像が表示されるか教えていただきたいです。 よろしくお願いします。

  • javaのpanelが表示されません

    下記のプログラムを作ったんですが、eclipseで実行するとフレームは表示されますが、空のフレームのような状態で、panelやボタンなどは表示されません。mainとは別のクラスで作成してるからなんでしょうか?よろしくお願いします。 import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class Table0 { public static void main(String[] args) { new Frame0(); } } class Frame0{ JFrame frame; JPanel panel; JScrollPane jsp; JTable table; DefaultTableModel dtm; public Frame0(){ frame=new JFrame("table"); frame.setBounds(30, 30, 300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); table=new JTable(8,5); jsp=new JScrollPane(table); jsp.setPreferredSize(new Dimension(250, 70)); panel=new JPanel(); panel.add(jsp); Container c=frame.getContentPane(); c.add(panel,BorderLayout.CENTER); } }

    • ベストアンサー
    • Java
  • javaのフレームにサイズがセットされてない?

    前回、http://okwave.jp/qa/q8069621.htmlで質問しました。 回答をもとにframe.setvisible(true)をコンストラクタの最後にするとうまくいき回答を締め切ったんですが・・・。 しかし、mainメソッドにframe.setvisible(true)を書くとフレームのタイトル部分だけとなり、 サイズがセットされないまま実行したときと同じようになってしまいます。 なぜでしょう?よろしくお願いします。 import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class Table0{ public static void main(String[] args) { Frame0 test=new Frame0(); test.setVisible(true); } } class Frame0 extends JFrame{ JFrame frame; JPanel panel; JScrollPane jsp; JTable table; DefaultTableModel dtm; public Frame0(){ frame=new JFrame("table"); frame.setBounds(30, 30, 300, 200); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); table=new JTable(8,5); jsp=new JScrollPane(table); jsp.setPreferredSize(new Dimension(250, 70)); panel=new JPanel(); panel.add(jsp); Container c=frame.getContentPane(); c.add(panel,BorderLayout.CENTER); } }

    • ベストアンサー
    • Java
  • Javaのプログラミング手伝ってください

    以下のソースコードを応用して、添付画像のような数字のかかれた画像を3つ並べてそれを回して7を揃えるというゲームを作りたいのですが全く進みません。どなたか完成させてくださいm(__)m使用する画像のファイル名は「slot1.jpeg」~「slot7.jpeg」です。 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.Timer; public class OneSlot extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; final int MAX = 7; Timer timer = new Timer(150 , this); JLabel label= new JLabel("スタートで始まるよ",JLabel.CENTER); JButton[] bt = {new JButton("スタート"),new JButton("ストップ")}; JLabel slot= new JLabel(new ImageIcon("Slot1.jpg"),JLabel.CENTER); ImageIcon[] slot_icon = new ImageIcon[MAX]; int iCount = 0; OneSlot(String title) { super(title); timer.setActionCommand("timer"); setBounds(200, 200, 230, 150); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); for(int i = 0;i < slot_icon.length; i++) slot_icon[i] = new ImageIcon("Slot" + (i+1) + ".jpg"); add("North",label); add("Center",slot); JPanel p = new JPanel(); for (int i = 0; i < bt.length;i++) { bt[i].addActionListener(this); p.add(bt[i]); } add("South",p); setVisible(true); } public static void main(String[] args) { new OneSlot("スロットマシン"); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); if(cmd.equals("timer")) { if(++iCount == slot_icon.length) iCount = 0; slot.setIcon(slot_icon[iCount]); } if(e.getSource() == bt[0] && !timer.isRunning()) { label.setText("7が当たりだよ"); timer.start(); } else if(e.getSource() == bt[1] && timer.isRunning()) { if(iCount+1 == MAX) label.setText("やった!!おめでとう"); else label.setText("残念でした"); timer.stop(); } } }

  • ボタンクリック後パネルを再描画repaintしたい

    ボタンをクリック後にstaticで保持していた値にプラス1して その値をパネルに再描画したいと思っています。 下記のプログラムだとボタンをクリックすると (<1<2<3<4)となって画像と数字が増えてしまいます 行いたいのは数字の部分だけが再描画されて カウントされて<3と表示されるだけになってもらいたい クラス1つ目 import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.event.MouseEvent; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Sample extends JFrame{ static int value=1; JPanel work = new JPanel(); public static void main(String[] args) { Sample frame = new Sample(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(100, 200, 200, 100); frame.add(frame.createPanel(), BorderLayout.LINE_END); frame.setVisible(true); } public JPanel createPanel() { ImageIcon icon = new ImageIcon("./img/left.gif"); JLabel label = new JLabel(); Cursor c = new Cursor(Cursor.HAND_CURSOR); label.setCursor(c); label.setIcon(icon); JLabel strLabel = new JLabel(); String str = Integer.toString(value); strLabel.setText(str); work.add(label); work.add(strLabel); label.addMouseListener(new myListener()); return work; } class myListener extends MouseAdapter{ public void mouseClicked(MouseEvent e){ System.out.print(Sample.value++); createPanel().repaint(); setVisible(true); } } } クラス2つ目 import java.awt.event.MouseEvent; import java.awt.event.MouseListener; public class MouseAdapter implements MouseListener{ public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} }

    • ベストアンサー
    • Java
  • JavaのSwingのレイアウト

    Swingを学習中ですが、うまくレイアウトできません。 添付した画像のようなレイアウトにしたいです。 作ってみたものは以下です。 import java.awt.BorderLayout; import java.awt.Color; import javax.swing.*; public class LayoutTest { public static void main(String[] args) { JFrame frame = new JFrame(); JPanel panel = new JPanel(); JTextField searchFiled = new JTextField("テキスト"); String[] comboboxString = {"C", "C++", "Java"}; JComboBox comboBox = new JComboBox(comboboxString); JButton button = new JButton("ボタン"); panel.add(comboBox, BorderLayout.EAST); panel.add(searchFiled, BorderLayout.CENTER); panel.add(button, BorderLayout.WEST); frame.add(panel, BorderLayout.PAGE_START); JPanel redPanel = new JPanel(); redPanel.setBackground(Color.RED); frame.add(redPanel); frame.setSize(700, 500); frame.setLocationRelativeTo(null); frame.setVisible(true); } }

    • ベストアンサー
    • Java
  • javaのBoxlayoutについて

    下記はBoxLayout用ののコードです。 Q1)Buttonのサイズを設定する方法がありますか? Q2)Buttonの配置を設定する方法がありますか? //===================================== import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.LayoutManager; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class AlignmentX extends JFrame{ JButton button1; JButton button2; JButton button3; public static void main(String[] args){ AlignmentX frame = new AlignmentX(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("タイトル"); frame.setVisible(true); } AlignmentX(){ button1 = new JButton("AAAAA"); button1.setAlignmentY(0.5f); button1.setPreferredSize(new Dimension(80,20)); button2 = new JButton("BBB"); button2.setAlignmentY(0.5f); button2.setPreferredSize(new Dimension(80,20)); button3 = new JButton("CC"); button3.setAlignmentY(0.5f); button3.setPreferredSize(new Dimension(80,20)); JPanel p = new JPanel(); p.setLayout((LayoutManager) new BoxLayout(p, BoxLayout.Y_AXIS)); p.add(button1); p.add(button2); p.add(button3); getContentPane().add(p, BorderLayout.CENTER); setBounds(10, 10, 300, 200); } } //以上,宜しくお願いします。

    • ベストアンサー
    • Java
  • Javaでタイマーの使い方

    Javaでタイマーの使い方作り方がわかりません import javax.swing.Timerこれつかいます。 package Test1; import javax.swing.Timer; public class Test1 { Timer TM = new Timer(10, null); public static void main(String[] args) { } } よろしくお願いします。

    • ベストアンサー
    • Java
  • javaでストップウォッチが上手く作れません

    あるサイトを参考にして作ってみたんですが うまく動いてくれません、多分おかしいところだらけですが どこがダメか教えてもらえるとありがたいです package timeP; import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; public class timeC extends JFrame implements Runnable { private JPanel contentPane; private JTextField textField; private Thread th = null; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { timeC frame = new timeC(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public timeC() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 85); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS)); JPanel panel_3 = new JPanel(); contentPane.add(panel_3); panel_3.setLayout(new BorderLayout(0, 0)); textField = new JTextField(); panel_3.add(textField, BorderLayout.CENTER); textField.setColumns(10); JPanel panel_2 = new JPanel(); contentPane.add(panel_2); panel_2.setLayout(new BorderLayout(0, 0)); JButton JButtonstart = new JButton(" 開始 "); JButtonstart.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if ( th == null ) { th = new Thread ( ); th.start(); } } }); panel_2.add(JButtonstart, BorderLayout.CENTER); JPanel panel_1 = new JPanel(); contentPane.add(panel_1); panel_1.setLayout(new BorderLayout(0, 0)); JButton JButtonstop = new JButton(" 停止 "); JButtonstop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if ( th != null ){ th = null; } } }); panel_1.add(JButtonstop, BorderLayout.CENTER); JPanel panel = new JPanel(); contentPane.add(panel); panel.setLayout(new BorderLayout(0, 0)); JButton btnNewButton_2 = new JButton("New button"); panel.add(btnNewButton_2, BorderLayout.CENTER); } @Override public void run() { //TODO 自動生成されたメソッド・スタブ int i; while ( th != null ){ i = Integer.parseInt( textField.getText() ); try { Thread.sleep(10000); if ( th == null ) break; } catch ( InterruptedException e ){ break; } textField.setText( Integer.toString( i + 1 ) ); } } }

専門家に質問してみよう