diff --git a/.gitignore b/.gitignore index 81e945b9..b42f5944 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ muon-jediterm/target/surefire-reports/TEST-org.muon.jediterm.AppTest.xml muon-main/target/maven-archiver/pom.properties muon-main/target/surefire-reports/muon.AppTest.txt muon-main/target/surefire-reports/TEST-muon.AppTest.xml +app/target/surefire-reports/* diff --git a/app/src/main/java/muon/panels/ErrorPanel.java b/app/src/main/java/muon/panels/ErrorPanel.java new file mode 100644 index 00000000..8ed2de6c --- /dev/null +++ b/app/src/main/java/muon/panels/ErrorPanel.java @@ -0,0 +1,33 @@ +package muon.panels; + +import muon.util.IconCode; +import muon.util.IconFont; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionListener; + +public class ErrorPanel extends JPanel { + public ErrorPanel(ActionListener errorAction) { + var label = new JLabel(); + label.setFont(IconFont.getSharedInstance().getIconFont(48.0f)); + label.setText(IconCode.RI_ACCOUNT_ALERT_FILL.getValue()); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + + var lblError = new JLabel("Operation failed"); + lblError.setBorder(new EmptyBorder(10, 10, 10, 10)); + lblError.setAlignmentX(Component.CENTER_ALIGNMENT); + + var button = new JButton("OK"); + button.setAlignmentX(Component.CENTER_ALIGNMENT); + button.addActionListener(errorAction); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(Box.createVerticalGlue()); + this.add(label); + this.add(lblError); + this.add(button); + this.add(Box.createVerticalGlue()); + } +} diff --git a/app/src/main/java/muon/panels/RetryPanel.java b/app/src/main/java/muon/panels/RetryPanel.java new file mode 100644 index 00000000..f20b6c04 --- /dev/null +++ b/app/src/main/java/muon/panels/RetryPanel.java @@ -0,0 +1,41 @@ +package muon.panels; + +import muon.util.IconCode; +import muon.util.IconFont; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.ActionListener; + +public class RetryPanel extends JPanel { + public RetryPanel(ActionListener retryCallback, ActionListener cancelCallback) { + var label = new JLabel(); + label.setFont(IconFont.getSharedInstance().getIconFont(48.0f)); + label.setText(IconCode.RI_ACCOUNT_ALERT_FILL.getValue()); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + + var lblError = new JLabel("Unable to connect"); + lblError.setBorder(new EmptyBorder(10, 10, 10, 10)); + lblError.setAlignmentX(Component.CENTER_ALIGNMENT); + + var btnRetry = new JButton("Try again"); + btnRetry.addActionListener(retryCallback); + var btnCancel = new JButton("Cencel"); + btnCancel.setAlignmentX(Component.CENTER_ALIGNMENT); + btnCancel.addActionListener(cancelCallback); + + var hb = Box.createHorizontalBox(); + hb.add(btnRetry); + hb.add(Box.createRigidArea(new Dimension(10, 10))); + hb.add(btnCancel); + hb.setAlignmentX(Component.CENTER_ALIGNMENT); + + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.add(Box.createVerticalGlue()); + this.add(label); + this.add(lblError); + this.add(hb); + this.add(Box.createVerticalGlue()); + } +} diff --git a/app/src/main/java/muon/panels/SpinnerPanel.java b/app/src/main/java/muon/panels/SpinnerPanel.java new file mode 100644 index 00000000..0d97be29 --- /dev/null +++ b/app/src/main/java/muon/panels/SpinnerPanel.java @@ -0,0 +1,25 @@ +package muon.panels; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; + +public class SpinnerPanel extends JPanel { + public SpinnerPanel() { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + var label = new JLabel("Please wait"); + label.setAlignmentX(Component.CENTER_ALIGNMENT); + label.setBorder(new EmptyBorder(10, 10, 10, 10)); + var prg = new JProgressBar(); + prg.setAlignmentX(Component.CENTER_ALIGNMENT); + prg.setPreferredSize(new Dimension(200, 5)); + prg.setMaximumSize(new Dimension(200, 5)); + prg.setIndeterminate(true); + + this.add(Box.createVerticalGlue()); + this.add(label); + this.add(prg); + this.add(Box.createVerticalGlue()); + } +} diff --git a/app/src/main/java/muon/screens/dialogs/UserInputDialog.java b/app/src/main/java/muon/screens/dialogs/UserInputDialog.java index dbf8e54e..c8257be3 100644 --- a/app/src/main/java/muon/screens/dialogs/UserInputDialog.java +++ b/app/src/main/java/muon/screens/dialogs/UserInputDialog.java @@ -1,5 +1,6 @@ package muon.screens.dialogs; +import muon.styles.AppTheme; import muon.util.IconCode; import muon.util.IconFont; @@ -53,48 +54,64 @@ public List getInputs(String label, String[] prompt, boolean[] echo) { } private void initUi() { - container = new JPanel(new GridBagLayout()); + container = new JPanel(); + container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS)); + loginButton = new JButton("Login"); loginButton.addActionListener(e -> { inputs = this.txtInputs.stream().map(txt -> new String(txt.getPassword())).toList(); setVisible(false); }); + var cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(e -> { + setVisible(false); + }); + var iconLabel = new JLabel(); iconLabel.setFont(IconFont.getSharedInstance().getIconFont(48.0f)); - iconLabel.setText(IconCode.RI_ACCOUNT_CIRCLE_FILL.getValue()); + iconLabel.setText(IconCode.RI_LOCK_PASSWORD_LINE.getValue()); + iconLabel.setAlignmentY(Component.TOP_ALIGNMENT); lblUser = new JLabel(); - lblUser.setText("user"); - lblUser.setBorder(new EmptyBorder(0, 0, 8, 0)); - lblUser.setFont(new Font(Font.DIALOG, Font.BOLD, 16)); + lblUser.setText("server\\user"); + lblUser.setBorder(new EmptyBorder(5, 0, 10, 0)); + lblUser.setFont(new Font(Font.DIALOG, Font.PLAIN, 14)); + lblUser.setForeground(AppTheme.INSTANCE.getDarkForeground()); lblUser.setAlignmentX(Component.LEFT_ALIGNMENT); - var iconPanel = new JPanel(new BorderLayout(10, 0)); - iconPanel.setAlignmentX(Component.LEFT_ALIGNMENT); - iconPanel.add(iconLabel, BorderLayout.WEST); - iconPanel.add(lblUser, BorderLayout.CENTER); - - var hbox = Box.createHorizontalBox(); - hbox.add(Box.createHorizontalGlue()); - hbox.add(loginButton); - hbox.setMaximumSize(new Dimension(Short.MAX_VALUE, hbox.getPreferredSize().height)); - hbox.setAlignmentX(Component.LEFT_ALIGNMENT); - userInputContainer = new JPanel(); userInputContainer.setAlignmentX(Component.LEFT_ALIGNMENT); userInputContainer.setLayout(new BoxLayout(userInputContainer, BoxLayout.Y_AXIS)); + var lblTitle = new JLabel("Authentication required"); + lblTitle.setFont(new Font(Font.DIALOG, Font.PLAIN, 18)); + lblTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + var hbox2 = Box.createHorizontalBox(); + hbox2.setAlignmentX(Component.LEFT_ALIGNMENT); + hbox2.add(Box.createHorizontalGlue()); + hbox2.add(loginButton); + hbox2.add(Box.createRigidArea(new Dimension(10, 10))); + hbox2.add(cancelButton); + var vbox = Box.createVerticalBox(); - vbox.add(iconPanel); + vbox.add(lblTitle); + vbox.add(lblUser); vbox.add(Box.createRigidArea(new Dimension(10, 20))); vbox.add(userInputContainer); - vbox.add(Box.createRigidArea(new Dimension(10, 10))); - vbox.add(hbox); - - container.add(vbox, new GridBagConstraints()); + vbox.add(Box.createRigidArea(new Dimension(10, 30))); + vbox.add(Box.createVerticalGlue()); + vbox.add(hbox2); + vbox.setAlignmentY(Component.TOP_ALIGNMENT); + + container.add(iconLabel); + container.add(Box.createRigidArea(new Dimension(10, 10))); + container.add(vbox); + container.setBorder(new EmptyBorder(15, 15, 15, 15)); } + private void showPrompt(String label, String[] prompt, boolean[] echo) { var len = prompt.length; lblUser.setText(label); @@ -111,6 +128,9 @@ private void showPrompt(String label, String[] prompt, boolean[] echo) { if (echo[i]) { txtInput.setEchoChar('*'); } + var d = txtInput.getPreferredSize(); + txtInput.setMaximumSize(new Dimension(Short.MAX_VALUE, d.height)); + txtInput.setPreferredSize(d); txtInputs.add(txtInput); var lbl = new JLabel(prompt[i]); lbl.setBorder(new EmptyBorder(0, 0, 10, 0)); @@ -120,7 +140,8 @@ private void showPrompt(String label, String[] prompt, boolean[] echo) { userInputContainer.add(txtInput); } this.pack(); - this.setLocationRelativeTo(null); + this.setSize(Math.max(400, this.getWidth()), Math.max(300, this.getHeight())); + this.setLocationRelativeTo(this.getOwner()); this.setVisible(true); } } diff --git a/app/src/main/java/muon/service/UserInputServiceImpl.java b/app/src/main/java/muon/service/UserInputServiceImpl.java index 28511a45..7a907c1b 100644 --- a/app/src/main/java/muon/service/UserInputServiceImpl.java +++ b/app/src/main/java/muon/service/UserInputServiceImpl.java @@ -14,7 +14,7 @@ public UserInputServiceImpl(UserInputDialog userInputDialog, BannerDialog banner @Override public synchronized String[] getUserInput(String text1, String text2, String[] prompt, boolean[] echo) { - var userInputs = userInputDialog.getInputs(text2 + "@" + text1, prompt, echo); + var userInputs = userInputDialog.getInputs(text1 + "\\" + text2, prompt, echo); if (userInputs.size() > 0) { return userInputs.toArray(new String[0]); }