Java tutorial
/* * Copyright 2017 Patrik Karlsson. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package se.trixon.mapollage.ui; import com.apple.eawt.AppEvent; import com.apple.eawt.Application; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JProgressBar; import javax.swing.JSeparator; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.filechooser.FileNameExtensionFilter; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.SystemUtils; import se.trixon.almond.util.AlmondOptions; import se.trixon.almond.util.AlmondOptionsPanel; import se.trixon.almond.util.AlmondUI; import se.trixon.almond.util.Dict; import se.trixon.almond.util.PomInfo; import se.trixon.almond.util.SystemHelper; import se.trixon.almond.util.swing.LogPanel; import se.trixon.almond.util.swing.SwingHelper; import se.trixon.almond.util.swing.dialogs.MenuModePanel; import se.trixon.almond.util.swing.dialogs.Message; import se.trixon.almond.util.swing.dialogs.SimpleDialog; import se.trixon.almond.util.swing.dialogs.about.AboutModel; import se.trixon.almond.util.swing.dialogs.about.AboutPanel; import se.trixon.mapollage.Mapollage; import se.trixon.mapollage.Operation; import se.trixon.mapollage.OperationListener; import se.trixon.mapollage.Options; import se.trixon.mapollage.ProfileManager; import se.trixon.mapollage.profile.Profile; /** * * @author Patrik Karlsson */ public class MainFrame extends javax.swing.JFrame { private static final boolean IS_MAC = SystemUtils.IS_OS_MAC; private final ResourceBundle mBundle = SystemHelper.getBundle(Mapollage.class, "Bundle"); private final ResourceBundle mBundleUI = SystemHelper.getBundle(MainFrame.class, "Bundle"); private ActionManager mActionManager; private final AlmondUI mAlmondUI = AlmondUI.getInstance(); private final AlmondOptions mAlmondOptions = AlmondOptions.getInstance(); private Thread mOperationThread; private final ProfileManager mProfileManager = ProfileManager.getInstance(); private LinkedList<Profile> mProfiles = mProfileManager.getProfiles(); private DefaultComboBoxModel mModel; private File mDestination; private OperationListener mOperationListener; private LogPanel mLogErrPanel; private LogPanel mLogOutPanel; private JProgressBar mProgressBar; private final Options mOptions = Options.getInstance(); private final StatusPanel mStatusPanel = new StatusPanel(); /** * Creates new form MainFrame */ public MainFrame() { initComponents(); mAlmondUI.addWindowWatcher(this); mAlmondUI.initoptions(); initActions(); init(); if (IS_MAC) { initMac(); } initMenus(); } private Profile getSelectedProfile() { if (mModel.getSize() == 0) { return new Profile(); } else { return (Profile) mModel.getSelectedItem(); } } private void init() { String fileName = String.format("/%s/icon-1024px.png", getClass().getPackage().getName().replace(".", "/")); ImageIcon imageIcon = new ImageIcon(getClass().getResource(fileName)); setIconImage(imageIcon.getImage()); configPanel.addStatusPanel(mStatusPanel); mProgressBar = mStatusPanel.getProgressBar(); mModel = (DefaultComboBoxModel) profileComboBox.getModel(); loadProfiles(); populateProfiles(null, 0); initListeners(); mLogErrPanel = mStatusPanel.getLogErrPanel(); mLogOutPanel = mStatusPanel.getLogOutPanel(); mLogOutPanel.println(mBundleUI.getString("welcome_1")); mLogOutPanel.println(Mapollage.getHelp()); mLogOutPanel.scrollToTop(); setRunningState(false); SwingUtilities.invokeLater(() -> { configPanel.setEnabled(!mProfiles.isEmpty()); }); } private void initActions() { mActionManager = ActionManager.getInstance().init(getRootPane().getActionMap(), getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)); InputMap inputMap = mPopupMenu.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap actionMap = mPopupMenu.getActionMap(); Action action = new AbstractAction("HideMenu") { @Override public void actionPerformed(ActionEvent e) { mPopupMenu.setVisible(false); } }; String key = "HideMenu"; actionMap.put(key, action); KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); inputMap.put(keyStroke, key); //about PomInfo pomInfo = new PomInfo(Mapollage.class, "se.trixon", "mapollage"); AboutModel aboutModel = new AboutModel(SystemHelper.getBundle(Mapollage.class, "about"), SystemHelper.getResourceAsImageIcon(MainFrame.class, "icon-1024px.png")); aboutModel.setAppVersion(pomInfo.getVersion()); AboutPanel aboutPanel = new AboutPanel(aboutModel); action = AboutPanel.getAction(MainFrame.this, aboutPanel); getRootPane().getActionMap().put(ActionManager.ABOUT, action); //File quitMenuItem.setAction(mActionManager.getAction(ActionManager.QUIT)); //Profile addMenuItem.setAction(mActionManager.getAction(ActionManager.ADD)); cloneMenuItem.setAction(mActionManager.getAction(ActionManager.CLONE)); renameMenuItem.setAction(mActionManager.getAction(ActionManager.RENAME)); removeMenuItem.setAction(mActionManager.getAction(ActionManager.REMOVE)); removeAllMenuItem.setAction(mActionManager.getAction(ActionManager.REMOVE_ALL)); //Tools optionsMenuItem.setAction(mActionManager.getAction(ActionManager.OPTIONS)); //Help helpMenuItem.setAction(mActionManager.getAction(ActionManager.HELP)); aboutDateFormatMenuItem.setAction(mActionManager.getAction(ActionManager.ABOUT_DATE_FORMAT)); aboutMenuItem.setAction(mActionManager.getAction(ActionManager.ABOUT)); //Toolbar startButton.setAction(mActionManager.getAction(ActionManager.START)); cancelButton.setAction(mActionManager.getAction(ActionManager.CANCEL)); menuButton.setAction(mActionManager.getAction(ActionManager.MENU)); SwingHelper.clearText(toolBar); } private void initListeners() { mOperationListener = new OperationListener() { private boolean success; @Override public void onOperationError(String message) { mLogErrPanel.println(message); } @Override public void onOperationFailed(String message) { onOperationFinished(message, 0); success = false; } @Override public void onOperationFinished(String message, int placemarkCount) { setRunningState(false); mLogOutPanel.println(message); if (mOptions.isAutoOpen() && success && placemarkCount > 0) { try { Desktop.getDesktop().open(mDestination); } catch (IOException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); } } } @Override public void onOperationInterrupted() { setRunningState(false); success = false; } @Override public void onOperationLog(String message) { mLogOutPanel.println(message); } @Override public void onOperationProcessingStarted() { SwingUtilities.invokeLater(() -> { mProgressBar.setIndeterminate(true); }); } @Override public void onOperationProgress(String message) { SwingUtilities.invokeLater(() -> { mProgressBar.setString(message); mProgressBar.setValue(mProgressBar.getValue() + 1); }); } @Override public void onOperationProgressInit(int fileCount) { SwingUtilities.invokeLater(() -> { mProgressBar.setIndeterminate(false); mProgressBar.setMinimum(0); mProgressBar.setValue(0); mProgressBar.setMaximum(fileCount); }); success = true; } @Override public void onOperationStarted() { setRunningState(true); } }; mActionManager.addAppListener(new ActionManager.AppListener() { @Override public void onCancel(ActionEvent actionEvent) { mOperationThread.interrupt(); } @Override public void onMenu(ActionEvent actionEvent) { if (actionEvent.getSource() != menuButton) { menuButtonMousePressed(null); } } @Override public void onOptions(ActionEvent actionEvent) { showOptions(); } @Override public void onQuit(ActionEvent actionEvent) { quit(); } @Override public void onStart(ActionEvent actionEvent) { if (!mProfiles.isEmpty()) { try { profileRun(); } catch (CloneNotSupportedException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); } } } }); mActionManager.addProfileListener(new ActionManager.ProfileListener() { @Override public void onAdd(ActionEvent actionEvent) { profileAdd(null); } @Override public void onClone(ActionEvent actionEvent) { try { profileClone(); } catch (CloneNotSupportedException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); } } @Override public void onEdit(ActionEvent actionEvent) { profileRename(getSelectedProfile().getName()); } @Override public void onRemove(ActionEvent actionEvent) { profileRemove(); } @Override public void onRemoveAll(ActionEvent actionEvent) { profileRemoveAll(); } }); } private void initMac() { Application macApplication = Application.getApplication(); macApplication.setAboutHandler((AppEvent.AboutEvent ae) -> { mActionManager.getAction(ActionManager.ABOUT).actionPerformed(null); }); macApplication.setPreferencesHandler((AppEvent.PreferencesEvent pe) -> { mActionManager.getAction(ActionManager.OPTIONS).actionPerformed(null); }); } private void initMenus() { if (mAlmondOptions.getMenuMode() == MenuModePanel.MenuMode.BUTTON) { mPopupMenu.add(addMenuItem); mPopupMenu.add(removeMenuItem); mPopupMenu.add(renameMenuItem); mPopupMenu.add(cloneMenuItem); mPopupMenu.add(removeAllMenuItem); mPopupMenu.add(new JSeparator()); if (!IS_MAC) { mPopupMenu.add(optionsMenuItem); mPopupMenu.add(new JSeparator()); } mPopupMenu.add(helpMenuItem); mPopupMenu.add(aboutDateFormatMenuItem); if (!IS_MAC) { mPopupMenu.add(aboutMenuItem); } if (!IS_MAC) { mPopupMenu.add(new JSeparator()); mPopupMenu.add(quitMenuItem); } } else { setJMenuBar(menuBar); if (IS_MAC) { fileMenu.remove(quitMenuItem); toolsMenu.remove(optionsMenuItem); helpMenu.remove(aboutMenuItem); } fileMenu.setVisible(fileMenu.getComponents().length > 0 || !IS_MAC); toolsMenu.setVisible(toolsMenu.getComponents().length > 0 || !IS_MAC); } menuButton.setVisible(mAlmondOptions.getMenuMode() == MenuModePanel.MenuMode.BUTTON); SwingHelper.clearToolTipText(menuBar); SwingHelper.clearToolTipText(mPopupMenu); } private void setRunningState(boolean state) { SwingUtilities.invokeLater(() -> { mActionManager.getAction(ActionManager.START).setEnabled(!state); mActionManager.getAction(ActionManager.CANCEL).setEnabled(state); mActionManager.getAction(ActionManager.ADD).setEnabled(!state); mActionManager.getAction(ActionManager.REMOVE).setEnabled(!state); mActionManager.getAction(ActionManager.CLONE).setEnabled(!state); mActionManager.getAction(ActionManager.OPTIONS).setEnabled(!state); mActionManager.getAction(ActionManager.REMOVE_ALL).setEnabled(!state); mActionManager.getAction(ActionManager.RENAME).setEnabled(!state); startButton.setVisible(!state); cancelButton.setVisible(state); configPanel.setEnabled(!state); mProgressBar.setString(" "); mProgressBar.setIndeterminate(false); }); } private void populateProfiles(Profile profile, int tab) { mModel.removeAllElements(); Collections.sort(mProfiles); mProfiles.stream().forEach((item) -> { mModel.addElement(item); }); if (profile != null) { mModel.setSelectedItem(profile); } SwingUtilities.invokeLater(() -> { configPanel.setEnabled(!mProfiles.isEmpty()); configPanel.selectTab(tab); mStatusPanel.getAutoOpenCheckBox().setEnabled(!mProfiles.isEmpty()); }); } private void loadProfiles() { configPanel.setEnabled(false); try { mProfileManager.load(); mProfiles = mProfileManager.getProfiles(); } catch (IOException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); } } private void profileAdd(String defaultName) { String s = requestProfileName(Dict.Dialog.TITLE_PROFILE_ADD.toString(), defaultName); if (s != null) { Profile existingProfile = mProfileManager.getProfile(s); if (existingProfile == null) { Profile p = new Profile(); p.setName(s); mProfiles.add(p); populateProfiles(p, 0); } else { Message.error(this, Dict.Dialog.ERROR.toString(), String.format(Dict.Dialog.ERROR_PROFILE_EXIST.toString(), s)); profileAdd(s); } } } private void profileClone() throws CloneNotSupportedException { Profile original = getSelectedProfile(); Profile p = original.clone(); mProfiles.add(p); populateProfiles(p, configPanel.getSelectedIndex()); String s = requestProfileName(Dict.Dialog.TITLE_PROFILE_CLONE.toString(), p.getName()); if (s != null) { p.setName(s); populateProfiles(getSelectedProfile(), configPanel.getSelectedIndex()); } else { mProfiles.remove(p); populateProfiles(original, configPanel.getSelectedIndex()); } } private void profileRemove() { if (!mProfiles.isEmpty()) { String message = String.format(Dict.Dialog.MESSAGE_PROFILE_REMOVE.toString(), getSelectedProfile().getName()); int retval = JOptionPane.showConfirmDialog(this, message, Dict.Dialog.TITLE_PROFILE_REMOVE.toString(), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); if (retval == JOptionPane.OK_OPTION) { mProfiles.remove(getSelectedProfile()); populateProfiles(null, 0); } } } private void profileRemoveAll() { if (!mProfiles.isEmpty()) { String message = String.format(Dict.Dialog.MESSAGE_PROFILE_REMOVE_ALL.toString(), getSelectedProfile().getName()); int retval = JOptionPane.showConfirmDialog(this, message, Dict.Dialog.TITLE_PROFILE_REMOVE_ALL.toString(), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE); if (retval == JOptionPane.OK_OPTION) { mProfiles.clear(); populateProfiles(null, 0); } } } private void profileRename(String defaultName) { String s = requestProfileName(Dict.Dialog.TITLE_PROFILE_RENAME.toString(), defaultName); if (s != null) { Profile existingProfile = mProfileManager.getProfile(s); if (existingProfile == null) { getSelectedProfile().setName(s); populateProfiles(getSelectedProfile(), configPanel.getSelectedIndex()); } else if (existingProfile != getSelectedProfile()) { Message.error(this, Dict.Dialog.ERROR.toString(), String.format(Dict.Dialog.ERROR_PROFILE_EXIST.toString(), s)); profileRename(s); } } } private void profileRun() throws CloneNotSupportedException { saveProfiles(); Profile profile = getSelectedProfile().clone(); if (profile.isValid()) { requestKmlFileObject(); } else { mLogErrPanel.clear(); mLogOutPanel.println(profile.getValidationError()); } } private void requestKmlFileObject() { FileNameExtensionFilter filter = new FileNameExtensionFilter("Keyhole Markup Language (*.kml)", "kml"); SimpleDialog.clearFilters(); SimpleDialog.addFilter(filter); SimpleDialog.setFilter(filter); SimpleDialog.setParent(this); if (mDestination == null) { SimpleDialog.setPath(FileUtils.getUserDirectory()); } else { SimpleDialog.setPath(mDestination.getParentFile()); SimpleDialog.setSelectedFile(new File("")); } if (SimpleDialog.saveFile(new String[] { "kml" })) { mDestination = SimpleDialog.getPath(); Profile profile = getSelectedProfile(); profile.setDestinationFile(mDestination); profile.isValid(); mStatusPanel.reset(); configPanel.reset(); if (profile.hasValidRelativeSourceDest()) { Operation operation = new Operation(mOperationListener, profile); mOperationThread = new Thread(operation); mOperationThread.start(); } else { mLogOutPanel.println(mBundle.getString("invalid_relative_source_dest")); mLogOutPanel.println(Dict.ABORTING.toString()); } } } private String requestProfileName(String title, String value) { return (String) JOptionPane.showInputDialog(this, null, title, JOptionPane.PLAIN_MESSAGE, null, null, value); } private void showOptions() { OptionsPanel optionsPanel = new OptionsPanel(); SwingHelper.makeWindowResizable(optionsPanel); Object[] options = new Object[] { AlmondOptionsPanel.getGlobalOptionsButton(optionsPanel), new JSeparator(), Dict.CANCEL, Dict.OK }; int retval = JOptionPane.showOptionDialog(this, optionsPanel, Dict.OPTIONS.toString(), JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, Dict.OK); if (retval == Arrays.asList(options).indexOf(Dict.OK)) { optionsPanel.save(); } } private void saveProfiles() { try { mProfileManager.save(); } catch (IOException ex) { Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex); } } private void quit() { dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } /** * This method is called from within the constructor to initialize the form. WARNING: Do NOT * modify this code. The content of this method is always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); mPopupMenu = new javax.swing.JPopupMenu(); menuBar = new javax.swing.JMenuBar(); fileMenu = new javax.swing.JMenu(); quitMenuItem = new javax.swing.JMenuItem(); profileMenu = new javax.swing.JMenu(); addMenuItem = new javax.swing.JMenuItem(); removeMenuItem = new javax.swing.JMenuItem(); renameMenuItem = new javax.swing.JMenuItem(); cloneMenuItem = new javax.swing.JMenuItem(); removeAllMenuItem = new javax.swing.JMenuItem(); toolsMenu = new javax.swing.JMenu(); optionsMenuItem = new javax.swing.JMenuItem(); helpMenu = new javax.swing.JMenu(); helpMenuItem = new javax.swing.JMenuItem(); aboutDateFormatMenuItem = new javax.swing.JMenuItem(); aboutMenuItem = new javax.swing.JMenuItem(); topPanel = new javax.swing.JPanel(); profileComboBox = new javax.swing.JComboBox<>(); toolBar = new javax.swing.JToolBar(); startButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); menuButton = new javax.swing.JButton(); configPanel = new se.trixon.mapollage.ui.config.ConfigPanel(); fileMenu.setText(Dict.FILE_MENU.toString()); fileMenu.add(quitMenuItem); menuBar.add(fileMenu); profileMenu.setText(Dict.PROFILE.toString()); profileMenu.add(addMenuItem); profileMenu.add(removeMenuItem); profileMenu.add(renameMenuItem); profileMenu.add(cloneMenuItem); profileMenu.add(removeAllMenuItem); menuBar.add(profileMenu); toolsMenu.setText(Dict.TOOLS.toString()); toolsMenu.add(optionsMenuItem); menuBar.add(toolsMenu); helpMenu.setText(Dict.HELP.toString()); helpMenu.add(helpMenuItem); helpMenu.add(aboutDateFormatMenuItem); helpMenu.add(aboutMenuItem); menuBar.add(helpMenu); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("se/trixon/mapollage/ui/Bundle"); // NOI18N setTitle(bundle.getString("MainFrame.title")); // NOI18N addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { formWindowClosing(evt); } }); topPanel.setLayout(new java.awt.GridBagLayout()); org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding( org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, configPanel, org.jdesktop.beansbinding.ELProperty.create("${enabled}"), profileComboBox, org.jdesktop.beansbinding.BeanProperty.create("enabled")); bindingGroup.addBinding(binding); profileComboBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { profileComboBoxActionPerformed(evt); } }); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; gridBagConstraints.weightx = 1.0; gridBagConstraints.insets = new java.awt.Insets(0, 4, 0, 0); topPanel.add(profileComboBox, gridBagConstraints); toolBar.setFloatable(false); toolBar.setRollover(true); startButton.setFocusable(false); startButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); startButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); toolBar.add(startButton); cancelButton.setFocusable(false); cancelButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); cancelButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); toolBar.add(cancelButton); menuButton.setFocusable(false); menuButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); menuButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); menuButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mousePressed(java.awt.event.MouseEvent evt) { menuButtonMousePressed(evt); } }); toolBar.add(menuButton); gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridx = 1; gridBagConstraints.gridy = 0; gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; topPanel.add(toolBar, gridBagConstraints); getContentPane().add(topPanel, java.awt.BorderLayout.PAGE_START); getContentPane().add(configPanel, java.awt.BorderLayout.CENTER); bindingGroup.bind(); pack(); }// </editor-fold>//GEN-END:initComponents private void menuButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_menuButtonMousePressed if (evt == null || evt.getButton() == MouseEvent.BUTTON1) { if (mPopupMenu.isVisible()) { mPopupMenu.setVisible(false); } else { mPopupMenu.show(menuButton, menuButton.getWidth() - mPopupMenu.getWidth(), mPopupMenu.getHeight()); int x = menuButton.getLocationOnScreen().x + menuButton.getWidth() - mPopupMenu.getWidth(); int y = menuButton.getLocationOnScreen().y + menuButton.getHeight(); mPopupMenu.setLocation(x, y); } } }//GEN-LAST:event_menuButtonMousePressed private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing saveProfiles(); }//GEN-LAST:event_formWindowClosing private void profileComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_profileComboBoxActionPerformed Profile p = getSelectedProfile(); SwingUtilities.invokeLater(() -> { configPanel.loadProfile(p); }); }//GEN-LAST:event_profileComboBoxActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JMenuItem aboutDateFormatMenuItem; private javax.swing.JMenuItem aboutMenuItem; private javax.swing.JMenuItem addMenuItem; private javax.swing.JButton cancelButton; private javax.swing.JMenuItem cloneMenuItem; private se.trixon.mapollage.ui.config.ConfigPanel configPanel; private javax.swing.JMenu fileMenu; private javax.swing.JMenu helpMenu; private javax.swing.JMenuItem helpMenuItem; private javax.swing.JPopupMenu mPopupMenu; private javax.swing.JMenuBar menuBar; private javax.swing.JButton menuButton; private javax.swing.JMenuItem optionsMenuItem; private javax.swing.JComboBox<Profile> profileComboBox; private javax.swing.JMenu profileMenu; private javax.swing.JMenuItem quitMenuItem; private javax.swing.JMenuItem removeAllMenuItem; private javax.swing.JMenuItem removeMenuItem; private javax.swing.JMenuItem renameMenuItem; private javax.swing.JButton startButton; private javax.swing.JToolBar toolBar; private javax.swing.JMenu toolsMenu; private javax.swing.JPanel topPanel; private org.jdesktop.beansbinding.BindingGroup bindingGroup; // End of variables declaration//GEN-END:variables }