以下は、ニュートンラフソン法を使用して、精度の高い平方根を見つける小さなプログラムです。スイング作業員がアプリケーションをフリーズする
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());
}
}
@Downvoter私はあなたがコメントを残そうと思ったら、なぜあなたがdownvotedを知って興味がありますか? – Dan