|
@@ -1,4 +1,138 @@
|
|
package holeg.ui;
|
|
package holeg.ui;
|
|
|
|
|
|
-public class SettingsWindow {
|
|
|
|
|
|
+import holeg.PowerFlowSettings;
|
|
|
|
+import holeg.SlackNodePlacementStrategy;
|
|
|
|
+
|
|
|
|
+import javax.swing.*;
|
|
|
|
+import javax.swing.event.ChangeListener;
|
|
|
|
+import java.awt.*;
|
|
|
|
+import java.util.function.Consumer;
|
|
|
|
+
|
|
|
|
+public class SettingsWindow extends JDialog {
|
|
|
|
+ public SettingsWindow(Frame owner, PowerFlowSettings settings) {
|
|
|
|
+ super(owner);
|
|
|
|
+
|
|
|
|
+ setTitle("HOLEG: Power flow settings");
|
|
|
|
+ setSize(400, 600);
|
|
|
|
+
|
|
|
|
+ getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
|
|
|
|
+
|
|
|
|
+ createCheckbox("Only update grid when changed", settings.onlyUpdateGridWhenChanged, (e) -> {
|
|
|
|
+ settings.onlyUpdateGridWhenChanged = e;
|
|
|
|
+ });
|
|
|
|
+ createCheckbox("Wait for solver job", settings.waitForSolverJob, (e) -> {
|
|
|
|
+ settings.waitForSolverJob = e;
|
|
|
|
+ });
|
|
|
|
+ createCheckbox("Skip grids with no producers", settings.skipGridsWithNoProducers, (e) -> {
|
|
|
|
+ settings.skipGridsWithNoProducers = e;
|
|
|
|
+ });
|
|
|
|
+ createCheckbox("Replace node with slack node", settings.replaceNodeWithSlackNode, (e) -> {
|
|
|
|
+ settings.replaceNodeWithSlackNode = e;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ createComboBox("Slack node placement strategy", SlackNodePlacementStrategy.values(), settings.slackNodePlacementStrategy, (e) -> {
|
|
|
|
+ settings.slackNodePlacementStrategy = e;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ createNumberTextBox("Max iterations", settings.solverSettings.maxIterations, (e) -> {
|
|
|
|
+ settings.solverSettings.maxIterations = e;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ createNumberTextBox("Jacobian recalculation interval", settings.solverSettings.jacobianRecalculationInterval, (e) -> {
|
|
|
|
+ settings.solverSettings.jacobianRecalculationInterval = e;
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ createNumberTextBox("Min voltage until invalid", settings.minVoltageUntilInvalid, (e) -> {
|
|
|
|
+ settings.minVoltageUntilInvalid = e;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void createCheckbox(String label, boolean value, Consumer<Boolean> listener) {
|
|
|
|
+ JCheckBox checkbox = new JCheckBox();
|
|
|
|
+ checkbox.setText(label);
|
|
|
|
+ checkbox.setSelected(value);
|
|
|
|
+ checkbox.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
|
|
+ checkbox.addActionListener((e) -> {
|
|
|
|
+ if (listener != null)
|
|
|
|
+ listener.accept(((JCheckBox) e.getSource()).isSelected());
|
|
|
|
+ });
|
|
|
|
+ add(checkbox);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private <T> void createComboBox(String label, T[] choices, T value, Consumer<T> listener) {
|
|
|
|
+ Container container = new Container();
|
|
|
|
+ container.setLayout(new BoxLayout(container, BoxLayout.LINE_AXIS));
|
|
|
|
+
|
|
|
|
+ // Add label
|
|
|
|
+ container.add(new JLabel(label));
|
|
|
|
+
|
|
|
|
+ // Create combo box
|
|
|
|
+ JComboBox<T> comboBox = new JComboBox<T>(choices);
|
|
|
|
+ comboBox.setSelectedItem(value);
|
|
|
|
+ comboBox.setMaximumSize(comboBox.getPreferredSize());
|
|
|
|
+ comboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
|
|
+ comboBox.addActionListener((e) -> {
|
|
|
|
+ if (listener != null)
|
|
|
|
+ listener.accept((T) ((JComboBox<T>) e.getSource()).getSelectedItem());
|
|
|
|
+ });
|
|
|
|
+ container.add(comboBox);
|
|
|
|
+ add(container);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private JTextField createTextField(String value) {
|
|
|
|
+ JTextField textField = new JTextField();
|
|
|
|
+ textField.setColumns(8);
|
|
|
|
+ textField.setText(value);
|
|
|
|
+ textField.setMaximumSize(textField.getPreferredSize());
|
|
|
|
+ textField.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
|
|
+ return textField;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void createNumberTextBox(String label, Integer value, Consumer<Integer> listener) {
|
|
|
|
+ Container container = new Container();
|
|
|
|
+ container.setLayout(new BoxLayout(container, BoxLayout.LINE_AXIS));
|
|
|
|
+
|
|
|
|
+ // Add label
|
|
|
|
+ container.add(new JLabel(label));
|
|
|
|
+
|
|
|
|
+ // Create text field
|
|
|
|
+ JTextField textField = createTextField(Integer.toString(value));
|
|
|
|
+ textField.addActionListener((e) -> {
|
|
|
|
+ if (listener != null) {
|
|
|
|
+ String text = ((JTextField) e.getSource()).getText();
|
|
|
|
+ try {
|
|
|
|
+ listener.accept(Integer.parseInt(text));
|
|
|
|
+ }
|
|
|
|
+ catch(NumberFormatException ignored) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ container.add(textField);
|
|
|
|
+ add(container);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void createNumberTextBox(String label, Double value, Consumer<Double> listener) {
|
|
|
|
+ Container container = new Container();
|
|
|
|
+ container.setLayout(new BoxLayout(container, BoxLayout.LINE_AXIS));
|
|
|
|
+
|
|
|
|
+ // Add label
|
|
|
|
+ container.add(new JLabel(label));
|
|
|
|
+
|
|
|
|
+ // Create text field
|
|
|
|
+ JTextField textField = createTextField(Double.toString(value));
|
|
|
|
+ textField.addActionListener((e) -> {
|
|
|
|
+ if (listener != null) {
|
|
|
|
+ String text = ((JTextField) e.getSource()).getText();
|
|
|
|
+ try {
|
|
|
|
+ listener.accept(Double.parseDouble(text));
|
|
|
|
+ }
|
|
|
|
+ catch(NumberFormatException ignored) {
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ container.add(textField);
|
|
|
|
+ add(container);
|
|
|
|
+ }
|
|
}
|
|
}
|