package holeg.ui; 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("Solver threads per subgrid", settings.maxSolverThreads, (e) -> { settings.maxSolverThreads = e; }); createNumberTextBox("Max iterations", settings.solverSettings.maxIterations, (e) -> { settings.solverSettings.maxIterations = e; }); createNumberTextBox("Min error", settings.solverSettings.minError, (e) -> { settings.solverSettings.minError = e; }); createNumberTextBox("Max error", settings.solverSettings.maxError, (e) -> { settings.solverSettings.maxError = e; }); createNumberTextBox("Jacobian recalculation interval", settings.solverSettings.jacobianRecalculationInterval, (e) -> { settings.solverSettings.jacobianRecalculationInterval = e; }); createNumberTextBox("Min voltage until invalid", settings.minVoltageUntilInvalid, (e) -> { settings.minVoltageUntilInvalid = e; }); createCheckbox("Disable automatic scaling", settings.disableAutomaticScaling, (e) -> { settings.disableAutomaticScaling = e; }); } private void createCheckbox(String label, boolean value, Consumer 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 void createComboBox(String label, T[] choices, T value, Consumer listener) { Container container = new Container(); container.setLayout(new BoxLayout(container, BoxLayout.LINE_AXIS)); // Add label container.add(new JLabel(label)); // Create combo box JComboBox comboBox = new JComboBox(choices); comboBox.setSelectedItem(value); comboBox.setMaximumSize(comboBox.getPreferredSize()); comboBox.setAlignmentX(Component.LEFT_ALIGNMENT); comboBox.addActionListener((e) -> { if (listener != null) listener.accept((T) ((JComboBox) 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 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.getDocument().addDocumentListener((SimpleDocumentListener)(e) -> { if (listener != null) { String text = textField.getText(); try { listener.accept(Integer.parseInt(text)); } catch(NumberFormatException ignored) { } } }); container.add(textField); add(container); } private void createNumberTextBox(String label, Double value, Consumer 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.getDocument().addDocumentListener((SimpleDocumentListener)(e) -> { if (listener != null) { String text = textField.getText(); try { listener.accept(Double.parseDouble(text)); } catch(NumberFormatException ignored) { } } }); container.add(textField); add(container); } }