import distributions.EvenDistribution;
import distributions.NormalDistribution;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.stage.Window;
import jfx.messagebox.MessageBox;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CalculatorControl implements Initializable
{
final private Stat stat = new Stat();
public TextField sizeField = new TextField();
public TextField param1 = new TextField();
public TextField param2 = new TextField();
public ChoiceBox<String> nType = new ChoiceBox<String>();
public Button startButton = new Button();
public Button stopButton = new Button();
public TextField coefPerc = new TextField();
public TextField exNumber = new TextField();
public ChoiceBox<String> distrType = new ChoiceBox<String>();
private MyRandom r = new MyRandom();
private int size = 0;
private double a = 0.5;
private double b = 10;
private boolean stopped = false;
private Timer updateScreenTimer;
private ExecutorService executorService;
@Override
public void initialize(URL url, ResourceBundle resourceBundle)
{
nType.getItems().add("4 соседа");
nType.getItems().add("8 соседей");
nType.setValue("4 соседа");
distrType.getItems().add("Равномерное распределение");
distrType.getItems().add("Нормальное распределение");
distrType.setValue("Равномерное распределение");
distrType.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>()
{
@Override
public void changed(ObservableValue<? extends Number> observableValue, Number number, Number number2)
{
if (number2.equals(0))
param2.setDisable(true);
else
param2.setDisable(false);
}
});
sizeField.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>()
{
@Override
public void handle(KeyEvent inputevent)
{
if (!inputevent.getCharacter().matches("\\d"))
{
inputevent.consume();
}
}
});
EventHandler<KeyEvent> eventHandler = new EventHandler<KeyEvent>()
{
@Override
public void handle(KeyEvent keyEvent)
{
if (!keyEvent.getCharacter().matches("[\\d , \\.]"))
{
keyEvent.consume();
}
}
};
param1.addEventFilter(KeyEvent.KEY_TYPED, eventHandler);
param2.addEventFilter(KeyEvent.KEY_TYPED, eventHandler);
}
public void startClick(ActionEvent actionEvent)
{
startButton.setDisable(true);
stopButton.setDisable(false);
stopped = false;
stat.reset();
if (!(parse() && checkInput()))
{
showMessageBox("Внимание!", "Проверьте ввод!", MessageBox.ICON_ERROR | MessageBox.OK);
startButton.setDisable(false);
stopButton.setDisable(true);
return;
}
checkChanges();
final Mode mode = getMode();
executorService = Executors.newCachedThreadPool();
executorService.submit(new Runnable()
{
@Override
public void run()
{
boolean result;
while (!stopped)
{
byte[][] bitMatrix = r.getBitMatrix(size);
result = new Percolation(bitMatrix, size, mode).isPercolated();
synchronized (stat)
{
if (result)
{
stat.update(1.0);
} else
{
stat.update(0.0);
}
}
}
}
});
TimerTask timerTask = new TimerTask()
{
@Override
public void run()
{
synchronized (stat)
{
Platform.runLater(new Runnable()
{
@Override
public void run()
{
coefPerc.setText(String.format("%1.16f", stat.getMean()));
exNumber.setText(String.valueOf(stat.getCount()));
}
});
}
}
};
updateScreenTimer = new Timer();
updateScreenTimer.schedule(timerTask, 500, 500);
}
public void stopClick(ActionEvent actionEvent)
{
startButton.setDisable(false);
stopButton.setDisable(true);
stopped = true;
updateScreenTimer.cancel();
executorService.shutdown();
}
private void showMessageBox(String title, String message, int option)
{
Window thisWindow = sizeField.getScene().getWindow();
MessageBox.show(thisWindow, message, title, option);
}
private Mode getMode()
{
Mode mode;
if (nType.getValue().equals("4 соседа"))
{
mode = Mode.ONE;
} else
{
mode = Mode.TWO;
}
return mode;
}
private boolean parse()
{
try
{
size = Integer.parseInt(sizeField.getText());
a = Double.parseDouble(param1.getText().replace(',', '.'));
b = Double.parseDouble(param2.getText().replace(',', '.'));
} catch (NumberFormatException e)
{
return false;
}
return true;
}
private boolean checkInput()
{
return size != 0;
}
private void checkChanges()
{
if (distrType.getValue().equals("Равномерное распределение"))
r = new MyRandom(new EvenDistribution(a));
else
r = new MyRandom(new NormalDistribution(a, b));
}
}