2017-01-18 12 views
1

以下は、ニュートンラフソン法を使用して、精度の高い平方根を見つける小さなプログラムです。スイング作業員がアプリケーションをフリーズする

SwingWorkerを除き、すべてが期待どおりに機能するようです。これが実行されると、アプリケーションはフリーズし、SwingWorkerがタスクを完了するまで使用できません。しかし、私はSwingWorkerの目的はこれを避けることだと思った。

誰かが問題を解決するのを手助けできますか?

import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyAdapter; 
import java.awt.event.KeyEvent; 
import java.math.BigDecimal; 
import java.math.RoundingMode; 
import java.util.concurrent.ExecutionException; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JSlider; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.SwingWorker; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 
import javax.swing.text.DefaultCaret; 

import net.miginfocom.swing.MigLayout; 

@SuppressWarnings("serial") 
public class SquareRoot extends JFrame { 
    private BigDecimal SQRT_DIG = new BigDecimal(150); 

    private SquareRoot() { 
     super("Square Rooter"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     createLayout(this); 
     pack(); 
     setLocationRelativeTo(null); 
     setVisible(true); 
    } 

    private void createLayout(JFrame addTo) { 
     JPanel rootPanel = new JPanel(new MigLayout("wrap", "grow", "")); 
     JLabel acc = new JLabel("Accuracy: " + SQRT_DIG); 
     JSlider accSlide = new JSlider(1, 1000000, 150); 
     JLabel numRoot = new JLabel("Number to Square Root"); 
     JTextField num = new JTextField(); 
     JButton root = new JButton("Root"); 
     JLabel ansRoot = new JLabel("Answer"); 
     JTextArea ans = new JTextArea(); 
     JScrollPane ansHolder = new JScrollPane(ans); 

     accSlide.addChangeListener(new ChangeListener() { 
      @Override 
      public void stateChanged(ChangeEvent arg0) { 
       SQRT_DIG = new BigDecimal(accSlide.getValue()); 
       acc.setText("Accuracy: " + SQRT_DIG); 
      } 
     }); 
     rootPanel.add(acc); 
     rootPanel.add(accSlide, "grow"); 

     root.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       ans.setText("Please Wait"); 
       new SwingWorker<BigDecimal, Object>() { 
        @Override 
        protected BigDecimal doInBackground() throws Exception { 
         return bigSqrt(new BigDecimal(num.getText())); 
        } 

        @Override 
        protected void done() { 
         try { 
          ans.setText(get().toPlainString()); 
         } catch (InterruptedException | ExecutionException e) { 
          e.printStackTrace(); 
         } 
        } 
       }.run(); 
      } 
     }); 
     rootPanel.add(numRoot); 
     rootPanel.add(num, "grow"); 
     rootPanel.add(root, "right"); 

     ans.setEditable(false); 
     ((DefaultCaret) ans.getCaret()).setUpdatePolicy(DefaultCaret.NEVER_UPDATE); 
     ansHolder.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 
     rootPanel.add(ansRoot); 
     rootPanel.add(ansHolder, "grow"); 

     addTo.add(rootPanel); 
    } 

    private BigDecimal sqrtNewtonRaphson(BigDecimal c, BigDecimal xn, BigDecimal precision) { 
     BigDecimal fx = xn.pow(2).add(c.negate()); 
     BigDecimal fpx = xn.multiply(new BigDecimal(2)); 
     BigDecimal xn1 = fx.divide(fpx,2*SQRT_DIG.intValue(),RoundingMode.HALF_DOWN); 
     xn1 = xn.add(xn1.negate()); 
     BigDecimal currentSquare = xn1.pow(2); 
     BigDecimal currentPrecision = currentSquare.subtract(c); 
     currentPrecision = currentPrecision.abs(); 
     if (currentPrecision.compareTo(precision) <= -1) 
      return xn1; 
     return sqrtNewtonRaphson(c, xn1, precision); 
    } 

    private BigDecimal bigSqrt(BigDecimal c) { 
     return sqrtNewtonRaphson(c, new BigDecimal(1), new BigDecimal(1).divide(new BigDecimal(10).pow(SQRT_DIG.intValue()))); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> new SquareRoot()); 
    } 
} 
+0

@Downvoter私はあなたがコメントを残そうと思ったら、なぜあなたがdownvotedを知って興味がありますか? – Dan

答えて

4

私はあなたの問題がSpringWorkerを実行手段にするrun()メソッドを使用して、あなたが原因であると考えています。代わりに​​を使用すると、ワーカーワーカーでワーカーワーカーを確実に実行できます。

+0

ご協力ありがとうございました – Dan

+0

歓迎:-) – JustDanyul

関連する問題