2016-12-27 22 views
0

私はウィンドウビルダーの助けを借りてGUIを組み込んだシンプルなJavaプログラムを作成しています。 GUIは単なるボタンで構成されています。Javaスレッドの開始 - 停止同じボタンをクリックして開始

ボタンをクリックすると、同じボタンをもう一度クリックして停止するまで無限に印刷されるスレッドを開始します。

はここ

LoopTest.java私のコードです

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
public class LoopTest extends JFrame implements ActionListener {//****** 
    private JButton startB, stopB; 
    private JTextArea oa; 
    Start sta; 

    public LoopTest(){ 
     super("Final Exam: Question "); 

     Container c = getContentPane(); 
     c.setLayout(new FlowLayout()); 

     startB = new JButton("START"); c.add(startB); 

     stopB = new JButton("STOP"); c.add(stopB); 

     oa = new JTextArea(5,20); c.add(oa); 
     c.add(new JScrollPane(oa)); 

     registerEvents(); 
     sta = new Start("Loop", oa); 

    } 
    public void registerEvents(){ 
     startB.addActionListener(
       new ActionListener(){ 
        public void actionPerformed(ActionEvent ae){ 
         if(startB.isEnabled() == true) 
          sta.setLoopFlag(true); 
         if(!sta.isAlive()) 
          sta.start(); 
         startB.setEnabled(false); 

        } 
       } 
     ); 

     stopB.addActionListener(
       new ActionListener(){ 
        public void actionPerformed(ActionEvent ae){ 
         if(stopB.isEnabled()==true){ 
          sta.setLoopFlag(false); 

         } 

        } 

     } 

     ); 
    } 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     // TODO Auto-generated method stub 

    } 
    public static void main(String[] args){ 
     LoopTest app = new LoopTest(); 
     app.setSize(300,300); 
     app.setLocationRelativeTo(null); 
     app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     app.setVisible(true); 
    } 

} 

Start.java

public class Start extends Thread { 

private JTextArea ta; 
    private boolean loopFlag; 

    public Start(String name, JTextArea ta){ 
     super(name); 
     this.ta = ta; 
     ta.setText(""); 
     loopFlag = true; 
    } 
    public void run(){ 
     int num=0; 
     while(true) 
      while(loopFlag){ 
       num = 1+ (int)(Math.random()*100); 
       ta.append(num + "\n"); 
      } 
    } 


    public void setLoopFlag(boolean value){ 
     loopFlag = value; 
    } 

} 

Stop.java事前に

public class Stop extends Thread { 
    public Stop(String name){ 
     super(name); 
    } 
    public void run(){ 

    } 
} 

感謝。

+0

あなたの質問は何ですか?単に「参照を置き換える」だけでスレッドを停止することはできません。 'Start'は外部(無駄な)ループのため停止しません。自明の質問、恐らく[mvce]を作成してください。 –

答えて

1

あなたのコードは、SwingイベントスレッドのSwingコンポーネントに対する変更を突然変更しているので、Swingスレッドルールを破ります。 提案:

  • スレッドを拡張しないでください。ほとんどの場合、Runnableを実装し、スレッド内でRunnableを使用する方がよいでしょう。
  • repaint()以外のSwing呼び出しをSwingイベントスレッドから外さないようにしてください。
  • while (true)は、「タイト」なループです。その中にはThread.sleepがありません。これは、タイトなループでCPUをタイピングする危険があり、プログラムやコンピュータを妨害する可能性があることを意味します。
  • スイングタイマーを使用することで、コードの問題をはるかに簡単かつきれいに解決できるため、直接バックグラウンドスレッディングを避けることをお勧めします。 Swing Timer Tutorial
  • start()およびstop()メソッドを呼び出すことで、このタイマーを簡単に開始および停止することができます。
  • 大量のデータをより簡単に処理できるので、JTextAreaよりも優先的にJListを使用します。
  • 私はJButtonにActionListenersではなくAbstractActionsを使用するのが好きで、この問題はその使用にうまく適合します。開始アクションと停止アクションを作成して、ボタンのアクションを単純に入れ替えることができます。たとえば、

import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 

@SuppressWarnings("serial") 
public class StartStop extends JPanel { 
    private static final int TIMER_DELAY = 300; 
    private StartAction startAction = new StartAction(); 
    private StopAction stopAction = new StopAction(); 
    private JButton button = new JButton(startAction); 
    private DefaultListModel<Integer> model = new DefaultListModel<>(); 
    private JList<Integer> jList = new JList<>(model); 
    private Timer timer = new Timer(TIMER_DELAY, new TimerListener()); 

    public StartStop() { 
     JPanel btnPanel = new JPanel(); 
     btnPanel.add(button); 

     jList.setFocusable(false); 
     jList.setVisibleRowCount(10); 
     jList.setPrototypeCellValue(100000); 
     JScrollPane scrollPane = new JScrollPane(jList); 

     setLayout(new BorderLayout()); 
     add(scrollPane, BorderLayout.CENTER); 
     add(btnPanel, BorderLayout.PAGE_END); 
    } 

    private class TimerListener implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      int num = 1 + (int) (Math.random() * 100); 
      model.addElement(num); 
     } 
    } 

    private class StartAction extends AbstractAction { 
     public StartAction() { 
      super("Start"); 
      putValue(MNEMONIC_KEY, KeyEvent.VK_S); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      timer.start(); 
      button.setAction(stopAction); 
     } 
    } 

    private class StopAction extends AbstractAction { 
     public StopAction() { 
      super("Stop"); 
      putValue(MNEMONIC_KEY, KeyEvent.VK_S); 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      timer.stop(); 
      button.setAction(startAction); 
     } 
    } 


    private static void createAndShowGui() { 
     JFrame frame = new JFrame("Start Stop"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(new StartStop()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 
関連する問題