diff options
| author | Simon Rettberg | 2015-10-22 16:51:54 +0200 |
|---|---|---|
| committer | Simon Rettberg | 2015-10-22 16:51:54 +0200 |
| commit | 1d87e00179d88ee1d7f06f8c8b53bbb584cf8d6b (patch) | |
| tree | f7812d727fb0b114d7be5a91254f10d0666e9083 | |
| parent | [client] Make list deselection more consistent with native behaviour, match s... (diff) | |
| download | tutor-module-1d87e00179d88ee1d7f06f8c8b53bbb584cf8d6b.tar.gz tutor-module-1d87e00179d88ee1d7f06f8c8b53bbb584cf8d6b.tar.xz tutor-module-1d87e00179d88ee1d7f06f8c8b53bbb584cf8d6b.zip | |
[client] Clean up config window, add config button to login dialog
7 files changed, 245 insertions, 122 deletions
diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java b/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java index 9cb002fa..664d2270 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/Config.java @@ -38,7 +38,6 @@ public class Config { */ public static final int FONT_SCALING_MIN = 75; public static final int FONT_SCALING_MAX = 175; - public static final int FONT_SCALING_STEP = 5; /** * Out property holder with all the setting keys diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/WordWrapLabel.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/WordWrapLabel.java new file mode 100644 index 00000000..956befec --- /dev/null +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/control/WordWrapLabel.java @@ -0,0 +1,95 @@ +package org.openslx.dozmod.gui.control; + +import java.awt.Component; +import java.awt.Dimension; + +import javax.swing.Icon; +import javax.swing.JLabel; + +/** + * A label that will use automatic word wrapping. + */ +public class WordWrapLabel extends JLabel { + + private static final long serialVersionUID = -2454459023556745689L; + + private String realText = ""; + + private boolean bold = false; + private boolean italic = false; + + public WordWrapLabel(String text, Icon icon, int horizontalAlignment) { + super(text, icon, horizontalAlignment); + } + + public WordWrapLabel(String text, int horizontalAlignment) { + this(text, null, horizontalAlignment); + } + + public WordWrapLabel(String text) { + this(text, null, LEADING); + } + + public WordWrapLabel(String text, boolean bold, boolean italic) { + this(null, null, LEADING); + this.bold = bold; + this.italic = italic; + setText(text); + } + + public WordWrapLabel(Icon image, int horizontalAlignment) { + this(null, image, horizontalAlignment); + } + + public WordWrapLabel(Icon image) { + this(null, image, CENTER); + } + + public WordWrapLabel() { + this("", null, LEADING); + } + + @Override + public void setText(String text) { + realText = text; + if (text != null && !text.isEmpty()) { + if (text.indexOf('&') != -1) { + text = text.replace("&", "&"); + } + if (text.indexOf('<') != -1) { + text = text.replace("<", "<"); + } + if (text.indexOf('>') != -1) { + text = text.replace(">", ">"); + } + String tmp = "<html>"; + if (bold) { + tmp += "<b>"; + } + if (italic) { + tmp += "<i>"; + } + text = tmp + text; + if (italic) { + text += "</i>"; + } + if (bold) { + text += "</b>"; + } + } + super.setText(text); + } + + @Override + public Dimension getMaximumSize() { + Component parent = this.getParent(); + if (parent == null) + return super.getMaximumSize(); + return parent.getMaximumSize(); + } + + public String getPlainText() { + return realText; + } + +} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/GridManager.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/GridManager.java index 0bf36c3a..b3b5f70e 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/GridManager.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/GridManager.java @@ -364,7 +364,7 @@ public class GridManager { * Set the anchor field of this {@link GridBagConstraints} instance. * * @param value - * @return + * @return This instance, so calls can be chained */ public GBC anchor(int value) { checkValid(); @@ -372,6 +372,18 @@ public class GridManager { return this; } + /** + * Set the insets field of this {@link GridBagConstraints} instance. + * + * @param insets + * @return This instance, so calls can be chained + */ + public GBC insets(Insets insets) { + checkValid(); + this.insets = insets; + return this; + } + // Extend with more helpers as needed private GBC(Component component, int spanX, int spanY) { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ConfigWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ConfigWindow.java index e7e406f7..932cf8c0 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ConfigWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/ConfigWindow.java @@ -1,6 +1,7 @@ package org.openslx.dozmod.gui.window; import java.awt.Frame; +import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -27,7 +28,7 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti private final static Logger LOGGER = Logger.getLogger(ConfigWindow.class); private SatelliteUserConfig userConfig = null; - public ConfigWindow(Frame modalParent) { + public ConfigWindow(Window modalParent) { super(modalParent); btnSave.setEnabled(false); @@ -51,15 +52,20 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti // -- SAT USER CONFIG -- // get the satellite user config and set the checkbox accordingly - userConfig = getSatUserConfig(); - if (userConfig != null) { - btnSendMeMail.setSelected(userConfig.isEmailNotifications()); + if (Session.getSatelliteToken() == null) { + chkSendMeMail.setEnabled(false); } else { - btnSendMeMail.setSelected(false); + userConfig = getSatUserConfig(); + if (userConfig != null) { + chkSendMeMail.setSelected(userConfig.isEmailNotifications()); + } else { + chkSendMeMail.setSelected(false); + } + chkSendMeMail.addActionListener(this); + lblYourAddress.setText("Ihre Adresse ist " + Session.getEMail()); } - btnSendMeMail.addActionListener(this); // -- END USER CONFIG -- - + ChangeListener changeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -69,9 +75,9 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti // -- FONT CONFIG -- // set font scaling as saved in config - btnFontSize.setValue(Config.getFontScaling()); - btnFontSize.addChangeListener(changeListener); - + sldFontSize.setValue(Config.getFontScaling()); + sldFontSize.addChangeListener(changeListener); + // Transfer connection count sldConnections.setValue(Config.getTransferConnectionCount()); sldConnections.addChangeListener(changeListener); @@ -80,6 +86,7 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti btnSave.addActionListener(this); btnClose.addActionListener(this); // -- END BOTTOM BUTTONS -- + pack(); } @Override @@ -101,9 +108,7 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti // our flag to en/disable the save button boolean changed = false; // first check our initial state - // TODO: Don't query this every time something changes ProxyMode initMode = Config.getProxyMode(); - SatelliteUserConfig userConfig = getSatUserConfig(); int fontScaling = Config.getFontScaling(); // now check if the buttons represent another state @@ -111,9 +116,9 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti changed = true; } else if (btnProxyAuto.isSelected() && initMode != ProxyMode.AUTO) { changed = true; - } else if (btnSendMeMail.isSelected() != userConfig.emailNotifications) { + } else if (chkSendMeMail.isSelected() != userConfig.emailNotifications) { changed = true; - } else if ((int) btnFontSize.getValue() != fontScaling) { + } else if ((int) sldFontSize.getValue() != fontScaling) { changed = true; } else if ((int) sldConnections.getValue() != Config.getTransferConnectionCount()) { changed = true; @@ -130,7 +135,7 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti userConfig = ThriftManager.getSatClient().getUserConfig(Session.getSatelliteToken()); } catch (TException e) { ThriftError.showMessage(this, LOGGER, e, - "Konnte die benutzerspezifische Konfiguration nicht vom Satelliten holen!"); + "Konnte die benutzerspezifische Konfiguration nicht vom Satelliten holen"); } return userConfig; } @@ -141,15 +146,17 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti // set mail me stuff as saved on the sat try { ThriftManager.getSatClient().setUserConfig(Session.getSatelliteToken(), config); + userConfig = config; } catch (TException e) { ThriftError.showMessage(this, LOGGER, e, - "Konnte die benutzerspezifische Konfiguration nicht vom Satelliten holen!"); + "Konnte die benutzerspezifische Konfiguration nicht auf dem Satelliten speichern"); return false; } return true; } private void saveOptions() { + boolean restartRequired = false; btnSave.setEnabled(false); // save proxy mode to config ProxyMode selectedMode = null; @@ -158,30 +165,36 @@ public class ConfigWindow extends ConfigWindowLayout implements UiFeedback, Acti if (btnProxyNone.isSelected()) selectedMode = ProxyMode.NONE; if (selectedMode != null) { + restartRequired = restartRequired || Config.getProxyMode() != selectedMode; Config.setProxyMode(selectedMode); } // save font scaling to config - Config.setFontScaling((int) btnFontSize.getValue()); + int newFontScaling = (int) sldFontSize.getValue(); + restartRequired = restartRequired || Config.getFontScaling() != newFontScaling; + Config.setFontScaling(newFontScaling); + // transfers Config.setTransferConnectionCount((int) sldConnections.getValue()); - // NOTE this can fail! // save mail notification stuff to sat - if (!setSatUserConfig(new SatelliteUserConfig(btnSendMeMail.isSelected()))) { - Gui.showMessageBox(this, "Konnte die Änderung nicht am Satelliten speichern!", MessageType.ERROR, - LOGGER, null); + if (Session.getSatelliteToken() != null + && !setSatUserConfig(new SatelliteUserConfig(chkSendMeMail.isSelected()))) { + // If saving failed, re-enable button btnSave.setEnabled(true); } - // let the user know he needs to restart for the changes to apply - Gui.showMessageBox(this, "Die Änderungen werden erst nach einem Programmneustart wirksam.", - MessageType.INFO, LOGGER, null); + + if (restartRequired) { + // let the user know he needs to restart for the changes to apply + Gui.showMessageBox(this, "Die Änderungen werden erst nach einem Programmneustart wirksam.", + MessageType.INFO, null, null); + } } public static boolean shouldBeShown() { return true; } - public static void open(Frame modalParent) { + public static void open(Window modalParent) { ConfigWindow win = new ConfigWindow(modalParent); MainWindow.centerShell(win); win.setVisible(true); diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java index 553378fd..d3229a4c 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/LoginWindow.java @@ -190,6 +190,13 @@ public class LoginWindow extends LoginWindowLayout { } }); + btnSettings.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ConfigWindow.open(LoginWindow.this); + } + }); + // finally check if we had a saved username String savedUsername = Config.getUsername(); if (savedUsername != null && !savedUsername.isEmpty()) { diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ConfigWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ConfigWindowLayout.java index fdcc69d1..546a5486 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ConfigWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/ConfigWindowLayout.java @@ -1,9 +1,8 @@ package org.openslx.dozmod.gui.window.layout; import java.awt.BorderLayout; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Frame; +import java.awt.Insets; +import java.awt.Window; import javax.swing.BorderFactory; import javax.swing.Box; @@ -20,104 +19,113 @@ import javax.swing.JSlider; import org.openslx.dozmod.Config; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.control.QLabel; +import org.openslx.dozmod.gui.control.WordWrapLabel; import org.openslx.dozmod.gui.helper.GridManager; -import org.openslx.dozmod.thrift.Session; @SuppressWarnings("serial") public class ConfigWindowLayout extends JDialog { private static String title = "bwLehrpool Suite - Konfiguration"; - protected JRadioButton btnProxyNone; - protected JRadioButton btnProxyAuto; - protected JRadioButton btnProxySocks; - protected JRadioButton btnProxyHttp; - protected JCheckBox btnSendMeMail; - protected JSlider btnFontSize; + protected final JRadioButton btnProxyNone; + protected final JRadioButton btnProxyAuto; + protected final JRadioButton btnProxySocks = null; + protected final JRadioButton btnProxyHttp = null; + protected final JCheckBox chkSendMeMail; + protected final QLabel lblYourAddress; + protected final JSlider sldFontSize; protected final JSlider sldConnections; - protected JButton btnSave; - protected JButton btnClose; + protected final JButton btnSave; + protected final JButton btnClose; - protected ButtonGroup radioGroup; - - public ConfigWindowLayout(Frame modalParent) { + public ConfigWindowLayout(Window modalParent) { super(modalParent, title, modalParent != null ? ModalityType.APPLICATION_MODAL : ModalityType.MODELESS); // regular layout as a helper for the whole page - setLayout(new BorderLayout()); - setMinimumSize(Gui.getScaledDimension(500, 300)); + getContentPane().setLayout(new BorderLayout()); + Insets headingInset = new Insets(16, 12, 3, 3); // Panel to add everything into, needed for the border. JPanel contentPanel = new JPanel(); getContentPane().add(contentPanel, BorderLayout.CENTER); - - // -- one panel per option for borders -- - // mail config panel - JPanel mailPanel = new JPanel(); - mailPanel.setLayout(new BoxLayout(mailPanel, BoxLayout.PAGE_AXIS)); - mailPanel.setBorder(BorderFactory.createTitledBorder("eMail-Benachrichtigungen")); - btnSendMeMail = new JCheckBox("Über Image- und Veranstaltungsänderungen per eMail informiert werden"); - mailPanel.add(btnSendMeMail); - // TODO center the label horizontally - QLabel mailNotice = new QLabel( - "Für diese Option muss der Server für den Mailversand konfiguriert sein."); - mailPanel.add(mailNotice); - QLabel mailNote = new QLabel("Ihre eMail-Adresse ist " + Session.getEMail()); - mailNote.setFont(mailNote.getFont().deriveFont(Font.ITALIC)); - mailPanel.add(mailNote); - - // proxy config panel - JPanel proxyPanel = new JPanel(); - proxyPanel.setBorder(BorderFactory.createTitledBorder("Proxy")); - GridManager proxyGrid = new GridManager(proxyPanel, 2); - proxyGrid.skip(2).fill(true, false).expand(true, false); - proxyGrid.nextRow(); - - // radio button for proxy mode + GridManager grid = new GridManager(contentPanel, 1, false, new Insets(4, 3, 1, 3)); + + // mail config + grid.add(new WordWrapLabel("E-Mail-Benachrichtigungen", true, false)) + .insets(headingInset) + .expand(true, false) + .fill(true, false); + chkSendMeMail = new JCheckBox("Über VM- und Veranstaltungsänderungen per E-Mail informiert werden"); + grid.add(chkSendMeMail).fill(true, false).expand(true, false); + grid.add( + new WordWrapLabel("Für diese Option muss der Server" + + " für den Mailversand konfiguriert sein.", false, true)) + .expand(true, false) + .fill(true, false); + lblYourAddress = new QLabel(); + grid.add(lblYourAddress).fill(true, false).expand(true, false); + + // proxy config + grid.add(new WordWrapLabel("Proxyserver", true, false)) + .insets(headingInset) + .fill(true, false) + .expand(true, false); JPanel radioGroupPanel = new JPanel(); - radioGroup = new ButtonGroup(); + radioGroupPanel.setLayout(new BoxLayout(radioGroupPanel, BoxLayout.LINE_AXIS)); + // radio buttons + ButtonGroup radioGroup = new ButtonGroup(); btnProxyNone = new JRadioButton("Keinen Proxy verwenden"); btnProxyAuto = new JRadioButton("Automatisch nach Proxy suchen"); radioGroup.add(btnProxyNone); radioGroup.add(btnProxyAuto); - radioGroupPanel.add(btnProxyNone); radioGroupPanel.add(btnProxyAuto); - proxyGrid.add(radioGroupPanel, 2); - proxyGrid.nextRow(); - proxyGrid.finish(false); - - // font config panel - JPanel fontPanel = new JPanel(); - fontPanel.setBorder(BorderFactory.createTitledBorder("Schriftgröße (%)")); - GridManager fontGrid = new GridManager(fontPanel, 1); - QLabel fontNote = new QLabel("Diese Funktion ist experimentell. Es kann zu Anzeigefehlern kommen."); - fontNote.setFont(fontNote.getFont().deriveFont(Font.ITALIC)); - fontGrid.add(fontNote); - fontGrid.nextRow(); - btnFontSize = new JSlider(JSlider.HORIZONTAL); - btnFontSize.setModel(new DefaultBoundedRangeModel(100, Config.FONT_SCALING_STEP, - Config.FONT_SCALING_MIN, Config.FONT_SCALING_MAX)); - btnFontSize.setMinorTickSpacing(Config.FONT_SCALING_STEP); - btnFontSize.setMajorTickSpacing(25); - btnFontSize.setSnapToTicks(true); - btnFontSize.setPaintTicks(true); - btnFontSize.setPaintLabels(true); - fontGrid.add(btnFontSize).fill(true, false).expand(true, false); - fontGrid.nextRow(); - fontGrid.finish(false); + grid.add(radioGroupPanel).expand(true, false).fill(true, false); + + // font config + grid.add(new WordWrapLabel("Schriftgröße (%)", true, false)) + .insets(headingInset) + .fill(true, false) + .expand(true, false); + grid.add( + new WordWrapLabel("Diese Funktion ist experimentell. Es kann zu Anzeigefehlern kommen.", + false, true)) + .expand(true, false) + .fill(true, false); + sldFontSize = new JSlider(JSlider.HORIZONTAL); + sldFontSize.setModel(new DefaultBoundedRangeModel(100, 0, Config.FONT_SCALING_MIN, + Config.FONT_SCALING_MAX)); + sldFontSize.setMinorTickSpacing(5); + sldFontSize.setMajorTickSpacing(25); + sldFontSize.setSnapToTicks(true); + sldFontSize.setPaintTicks(true); + sldFontSize.setPaintLabels(true); + grid.add(sldFontSize).fill(true, false).expand(true, false); // Concurrent Connections + grid.add(new WordWrapLabel("Verbindungen pro Transfer", true, false)) + .insets(headingInset) + .fill(true, false) + .expand(true, false); + grid.add( + new WordWrapLabel("Im Normalfall werden beste Ergebnisse erzielt," + + " wenn die Einstellung auf 1 belassen wird. Falls die Übertragungsgeschwindigkeit" + + " ihre Netzwerkanbindung nicht auslastet, probieren Sie den nächsthöheren" + + " Wert. Zu hohe Werte können einen negativen Effekt auf die" + + " Übertragungsgeschwindigkeit haben, und belasten den Satelliten-Server stärker.", + false, true)) + .fill(true, false) + .expand(true, false); sldConnections = new JSlider(JSlider.HORIZONTAL); - sldConnections.setModel(new DefaultBoundedRangeModel(1, 1, 1, 4)); - sldConnections.setSnapToTicks(true); - JPanel pnlConnections = new JPanel(); - pnlConnections.setLayout(new BoxLayout(pnlConnections, BoxLayout.PAGE_AXIS)); - pnlConnections.setBorder(BorderFactory.createTitledBorder("Verbindungen pro Transfer (DEBUG/TESTING)")); - pnlConnections.add(new QLabel("Anzahl Verbindungen pro Up/Download. Empfohlene Einstellung: 1")); - pnlConnections.add(sldConnections); + sldConnections.setModel(new DefaultBoundedRangeModel(1, 0, 1, 4)); + sldConnections.setPaintTicks(true); + sldConnections.setPaintLabels(true); + grid.add(sldConnections).expand(true, false).fill(true, false); + + // Finish + grid.finish(true); // bottom button panel JPanel buttonPanel = new JPanel(); @@ -128,26 +136,9 @@ public class ConfigWindowLayout extends JDialog { buttonPanel.add(Box.createGlue()); buttonPanel.add(btnClose); buttonPanel.add(btnSave); - - // Start the grid stuff - GridManager grid = new GridManager(contentPanel, 1); - grid.add(mailPanel).fill(true, false).expand(false, false); - grid.nextRow(); - grid.add(Box.createRigidArea(new Dimension(0, 10))); - grid.nextRow(); - grid.add(proxyPanel).fill(true, false).expand(false, false); - grid.nextRow(); - grid.add(Box.createRigidArea(new Dimension(0, 10))); - grid.nextRow(); - grid.add(fontPanel).fill(true, false).expand(false, false); - grid.nextRow(); - grid.add(Box.createRigidArea(new Dimension(0, 10))); - grid.nextRow(); - grid.add(pnlConnections).fill(true, false).expand(false, false); - grid.nextRow(); - grid.finish(false); - getContentPane().add(buttonPanel, BorderLayout.PAGE_END); - pack(); + + setPreferredSize(Gui.getScaledDimension(500, 600)); } + } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LoginWindowLayout.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LoginWindowLayout.java index fd5d71ad..4b1db451 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LoginWindowLayout.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/window/layout/LoginWindowLayout.java @@ -3,6 +3,7 @@ package org.openslx.dozmod.gui.window.layout; import java.awt.Frame; import java.awt.Rectangle; +import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.ImageIcon; @@ -51,7 +52,8 @@ public abstract class LoginWindowLayout extends JDialog { private static final String LOGIN_FORM_LABEL = "Zugangsdaten"; // login type panel - protected JRadioButton[] loginTypes = new JRadioButton[3]; + protected final JRadioButton[] loginTypes = new JRadioButton[3]; + protected final JButton btnSettings; // login form panel protected final JComboBox<Organization> idpCombo; @@ -80,6 +82,7 @@ public abstract class LoginWindowLayout extends JDialog { loginTypes[0] = new JRadioButton("Authentifizierung über bwIDM"); loginTypes[1] = new JRadioButton("Test-Zugang mit festem Benutzer"); loginTypes[2] = new JRadioButton("Direkter Zugang zum Satelliten"); + btnSettings = new JButton("Einstellungen"); idpCombo = new ComboBox<>(new ComboBoxRenderer<Organization>() { @Override @@ -105,7 +108,7 @@ public abstract class LoginWindowLayout extends JDialog { grid.add(loginFormPanel).expand(0.75, 1).fill(true, true); grid.nextRow(); - grid.finish(true); + grid.finish(false); } @@ -146,6 +149,9 @@ public abstract class LoginWindowLayout extends JDialog { loginTypeButtonGroup.add(loginTypes[i]); loginTypePanel.add(loginTypes[i]); } + loginTypePanel.add(Box.createVerticalGlue()); + loginTypePanel.add(btnSettings); + return loginTypePanel; } |
