Java tutorial
/* * This file is part of DRBD Management Console by LINBIT HA-Solutions GmbH * written by Rasto Levrinc. * * Copyright (C) 2009-2010, LINBIT HA-Solutions GmbH. * Copyright (C) 2009-2010, Rasto Levrinc * * DRBD Management Console is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2, or (at your option) * any later version. * * DRBD Management Console is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with drbd; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ package lcmc.common.ui; import com.google.common.base.Optional; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; import lcmc.cluster.ui.widget.Check; import lcmc.cluster.ui.widget.Label; import lcmc.cluster.ui.widget.Widget; import lcmc.cluster.ui.widget.WidgetFactory; import lcmc.common.domain.AccessMode; import lcmc.common.domain.Application; import lcmc.common.domain.ResourceValue; import lcmc.common.domain.Unit; import lcmc.common.domain.Value; import lcmc.common.domain.util.Tools; import lcmc.common.ui.utils.ButtonCallback; import lcmc.common.ui.utils.MyButton; import lcmc.common.ui.utils.SwingUtils; import lcmc.common.ui.utils.WidgetListener; import lcmc.crm.domain.CrmXml; import lcmc.logger.Logger; import lcmc.logger.LoggerFactory; import org.apache.commons.collections15.map.MultiKeyMap; import javax.inject.Inject; import javax.inject.Named; import javax.swing.*; import javax.swing.border.TitledBorder; import java.awt.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This class provides textfields, combo boxes etc. for editable info objects. */ @Named public abstract class EditableInfo extends Info { private static final Logger LOG = LoggerFactory.getLogger(EditableInfo.class); /** Whether is's a wizard element. */ public static final boolean WIZARD = true; /** Hash from parameter to boolean value if the last entered value was correct. */ private final Map<String, Boolean> paramCorrectValueMap = new ConcurrentHashMap<String, Boolean>(); private final Table<String, String, JPanel> sectionPanels = HashBasedTable.create(); /** Old apply button, is used for wizards. */ private MyButton oldApplyButton = null; private MyButton applyButton; private MyButton revertButton; /** Is counted down, first time the info panel is initialized. */ private CountDownLatch infoPanelLatch = new CountDownLatch(1); private final Collection<JPanel> advancedPanelList = new ArrayList<JPanel>(); private final Collection<String> advancedOnlySectionList = new ArrayList<String>(); private final JPanel moreOptionsPanel = new JPanel(); /** Whether dialog was started. It disables the apply button. */ private boolean dialogStarted = false; /** Disabled section, not visible. */ private final Collection<String> disabledSections = new HashSet<String>(); @Inject private Application application; @Inject private SwingUtils swingUtils; @Inject private WidgetFactory widgetFactory; @Inject private Access access; private Optional<ResourceValue> resource; public void einit(final Optional<ResourceValue> resource, final String name, final Browser browser) { super.init(name, browser); this.resource = resource; } protected abstract String getSection(String param); protected abstract boolean isRequired(String param); protected abstract boolean isAdvanced(String param); /** Returns null this parameter should be enabled. Otherwise return a reason that appears in the tooltip. */ protected abstract String isEnabled(String param); protected abstract AccessMode.Type getAccessType(String param); protected abstract AccessMode.Mode isEnabledOnlyInAdvancedMode(String param); protected abstract boolean isLabel(String param); protected abstract boolean isInteger(String param); protected abstract boolean isTimeType(String param); protected boolean hasUnitPrefix(final String param) { return false; } protected abstract boolean isCheckBox(String param); protected Widget.Type getFieldType(final String param) { return null; } protected abstract String getParamType(final String param); protected String getParamRegexp(final String param) { // TODO: this should be only for Pacemaker if (isInteger(param)) { return "^((-?\\d*|(-|\\+)?" + CrmXml.INFINITY_VALUE + '|' + CrmXml.DISABLED_IN_COMBOBOX + "))|@NOTHING_SELECTED@$"; } return null; } /** Returns the possible choices for pull down menus if applicable. */ protected abstract Value[] getParamPossibleChoices(String param); /** Returns array of all parameters. */ public abstract String[] getParametersFromXML(); // TODO: no XML /** How much of the info is used. */ public int getUsed() { return -1; } protected final void initApplyButton(final ButtonCallback buttonCallback) { initApplyButton(buttonCallback, Tools.getString("Browser.ApplyResource")); } protected final void initCommitButton(final ButtonCallback buttonCallback) { initApplyButton(buttonCallback, Tools.getString("Browser.CommitResources")); } /** Inits apply or commit button button. */ protected final void initApplyButton(final ButtonCallback buttonCallback, final String text) { if (oldApplyButton == null) { applyButton = widgetFactory.createButton(text, Browser.APPLY_ICON); application.makeMiniButton(applyButton); applyButton.setEnabled(false); oldApplyButton = applyButton; revertButton = widgetFactory.createButton(Tools.getString("Browser.RevertResource"), Browser.REVERT_ICON); revertButton.setEnabled(false); revertButton.setToolTipText(Tools.getString("Browser.RevertResource.ToolTip")); application.makeMiniButton(revertButton); revertButton.setPreferredSize(new Dimension(65, 50)); } else { applyButton = oldApplyButton; } applyButton.setEnabled(false); if (buttonCallback != null) { addMouseOverListener(applyButton, buttonCallback); } } /** Creates apply button and adds it to the panel. */ protected final void addApplyButton(final JPanel panel) { panel.add(applyButton, BorderLayout.LINE_START); } /** Creates revert button and adds it to the panel. */ protected final void addRevertButton(final JPanel panel) { final JPanel p = new JPanel(new FlowLayout(FlowLayout.TRAILING, 4, 0)); p.setBackground(Browser.BUTTON_PANEL_BACKGROUND); p.add(revertButton); panel.add(p, BorderLayout.CENTER); } /** Adds jlabel field with tooltip. */ public final void addLabelField(final JPanel panel, final String left, final String right, final int leftWidth, final int rightWidth, final int height) { final JLabel leftLabel = new JLabel(left); leftLabel.setToolTipText(left); final JLabel rightLabel = new JLabel(right); rightLabel.setToolTipText(right); addField(panel, leftLabel, rightLabel, leftWidth, rightWidth, height); } /** * Adds field with left and right component to the panel. Use panel * with spring layout for this. */ public final void addField(final JPanel panel, final java.awt.Component left, final java.awt.Component right, final int leftWidth, final int rightWidth, int height) { /* right component with fixed width. */ if (height == 0) { height = application.getDefaultSize("Browser.FieldHeight"); } Tools.setSize(left, leftWidth, height); panel.add(left); Tools.setSize(right, rightWidth, height); panel.add(right); right.setBackground(panel.getBackground()); } /** * Adds parameters to the panel in a wizard. * Returns number of rows. */ public final void addWizardParams(final JPanel optionsPanel, final String[] params, final MyButton wizardApplyButton, final int leftWidth, final int rightWidth, final Map<String, Widget> sameAsFields) { addParams(optionsPanel, Widget.WIZARD_PREFIX, params, wizardApplyButton, leftWidth, rightWidth, sameAsFields); } /** Adds parameters to the panel. */ public final void addParams(final JPanel optionsPanel, final String[] params, final int leftWidth, final int rightWidth, final Map<String, Widget> sameAsFields) { addParams(optionsPanel, null, params, applyButton, leftWidth, rightWidth, sameAsFields); } /** Adds parameters to the panel. */ private void addParams(final JPanel optionsPanel, final String prefix, final String[] params, final MyButton thisApplyButton, final int leftWidth, final int rightWidth, final Map<String, Widget> sameAsFields) { swingUtils.isSwingThread(); if (params == null) { return; } final MultiKeyMap<String, JPanel> panelPartsMap = new MultiKeyMap<String, JPanel>(); final Collection<PanelPart> panelPartsList = new ArrayList<PanelPart>(); final MultiKeyMap<String, Integer> panelPartRowsMap = new MultiKeyMap<String, Integer>(); for (final String param : params) { final Widget paramWi = createWidget(param, prefix, rightWidth); /* sub panel */ final String section = getSection(param); final JPanel panel; final AccessMode.Type accessType = getAccessType(param); final String accessTypeString = accessType.toString(); final Boolean advanced = isAdvanced(param); final String advancedString = advanced.toString(); if (panelPartsMap.containsKey(section, accessTypeString, advancedString)) { panel = panelPartsMap.get(section, accessTypeString, advancedString); panelPartRowsMap.put(section, accessTypeString, advancedString, panelPartRowsMap.get(section, accessTypeString, advancedString) + 1); } else { panel = new JPanel(new SpringLayout()); panel.setBackground(getSectionColor(section)); if (advanced) { advancedPanelList.add(panel); panel.setVisible(access.isAdvancedMode()); } panelPartsMap.put(section, accessTypeString, advancedString, panel); panelPartsList.add(new PanelPart(section, accessType, advanced)); panelPartRowsMap.put(section, accessTypeString, advancedString, 1); } /* label */ final JLabel label = new JLabel(getParamShortDesc(param)); final String longDesc = getParamLongDesc(param); paramWi.setLabel(label, longDesc); /* tool tip */ paramWi.setToolTipText(getToolTipText(param, paramWi)); label.setToolTipText(longDesc + additionalToolTip(param)); int height = 0; if (paramWi instanceof Label) { height = application.getDefaultSize("Browser.LabelFieldHeight"); } addField(panel, label, paramWi.getComponent(), leftWidth, rightWidth, height); } final boolean wizard = Widget.WIZARD_PREFIX.equals(prefix); for (final String param : params) { final Widget paramWi = getWidget(param, prefix); if (wizard) { final Widget rpwi = getWidget(param, null); if (rpwi == null) { LOG.error("addParams: unknown param: " + param); continue; } if (paramWi.getValue() == null || paramWi.getValue().isNothingSelected()) { rpwi.setValueAndWait(null); } else { final Value value = paramWi.getValue(); rpwi.setValueAndWait(value); } } } for (final String param : params) { final Widget paramWi = getWidget(param, prefix); Widget rpwi = null; if (wizard) { rpwi = getWidget(param, null); } final Widget realParamWi = rpwi; paramWi.addListeners(new WidgetListener() { @Override public void check(final Value value) { checkParameterFields(paramWi, realParamWi, param, getParametersFromXML(), thisApplyButton); } }); } /* add sub panels to the option panel */ final Map<String, JPanel> sectionMap = new HashMap<String, JPanel>(); final Collection<JPanel> notAdvancedSections = new HashSet<JPanel>(); final Collection<JPanel> advancedSections = new HashSet<JPanel>(); for (final PanelPart panelPart : panelPartsList) { final String section = panelPart.getSection(); final AccessMode.Type accessType = panelPart.getType(); final String accessTypeString = accessType.toString(); final Boolean advanced = panelPart.isAdvanced(); final String advancedString = advanced.toString(); final JPanel panel = panelPartsMap.get(section, accessTypeString, advancedString); final int rows = panelPartRowsMap.get(section, accessTypeString, advancedString); final int columns = 2; SpringUtilities.makeCompactGrid(panel, rows, columns, 1, 1, // initX, initY 1, 1); // xPad, yPad final JPanel sectionPanel; if (sectionMap.containsKey(section)) { sectionPanel = sectionMap.get(section); } else { sectionPanel = getParamPanel(getSectionDisplayName(section), getSectionColor(section)); sectionMap.put(section, sectionPanel); addSectionPanel(section, wizard, sectionPanel); optionsPanel.add(sectionPanel); if (sameAsFields != null) { final Widget sameAsCombo = sameAsFields.get(section); if (sameAsCombo != null) { final JPanel saPanel = new JPanel(new SpringLayout()); saPanel.setBackground(Browser.BUTTON_PANEL_BACKGROUND); final JLabel label = new JLabel(Tools.getString("ClusterBrowser.SameAs")); sameAsCombo.setLabel(label, ""); addField(saPanel, label, sameAsCombo.getComponent(), leftWidth, rightWidth, 0); SpringUtilities.makeCompactGrid(saPanel, 1, 2, 1, 1, // initX, initY 1, 1); // xPad, yPad sectionPanel.add(saPanel); } } } sectionPanel.setVisible(isSectionEnabled(section)); sectionPanel.add(panel); if (advanced) { advancedSections.add(sectionPanel); } else { notAdvancedSections.add(sectionPanel); } } boolean advanced = false; for (final Map.Entry<String, JPanel> sectionEntry : sectionMap.entrySet()) { final JPanel sectionPanel = sectionEntry.getValue(); if (advancedSections.contains(sectionPanel)) { advanced = true; } if (!notAdvancedSections.contains(sectionPanel)) { advancedOnlySectionList.add(sectionEntry.getKey()); sectionPanel.setVisible(access.isAdvancedMode() && isSectionEnabled(sectionEntry.getKey())); } } moreOptionsPanel.setVisible(advanced && !access.isAdvancedMode()); } /** Returns a more panel with "more options are available" message. */ public final JPanel getMoreOptionsPanel(final int width) { final JLabel l = new JLabel(Tools.getString("EditableInfo.MoreOptions")); final Font font = l.getFont(); final String name = font.getFontName(); final int style = Font.ITALIC; final int size = font.getSize(); l.setFont(new Font(name, style, size - 3)); moreOptionsPanel.setBackground(Browser.PANEL_BACKGROUND); moreOptionsPanel.add(l); final Dimension d = moreOptionsPanel.getPreferredSize(); d.width = width; moreOptionsPanel.setMaximumSize(d); return moreOptionsPanel; } /** Checks ands sets paramter fields. */ public void checkParameterFields(final Widget paramWi, final Widget realParamWi, final String param, final String[] params, final MyButton thisApplyButton) { final Thread thread = new Thread(new Runnable() { @Override public void run() { final Check check; if (realParamWi == null) { swingUtils.waitForSwing(); check = checkResourceFields(param, params); } else { swingUtils.invokeLater(new Runnable() { @Override public void run() { if (paramWi.getValue() == null || paramWi.getValue().isNothingSelected()) { realParamWi.setValueAndWait(null); } else { final Value value = paramWi.getValue(); realParamWi.setValueAndWait(value); } } }); swingUtils.waitForSwing(); check = checkResourceFields(param, params); } swingUtils.invokeLater(new Runnable() { @Override public void run() { if (resource.get().isNew()) { check.addChanged("new resource"); } if (thisApplyButton == applyButton) { /* not a wizard button */ if (isDialogStarted()) { check.addIncorrect("dialog started"); } thisApplyButton.setEnabled(check); } else { /* wizard button */ thisApplyButton.setEnabledCorrect(check); } if (revertButton != null) { revertButton.setEnabledChanged(check); } final String toolTip = getToolTipText(param, paramWi); paramWi.setToolTipText(toolTip); if (realParamWi != null) { realParamWi.setToolTipText(toolTip); } } }); } }); thread.start(); } /** Get stored value in the combo box. */ public final Value getComboBoxValue(final String param) { final Widget wi = getWidget(param, null); if (wi == null) { return null; } return wi.getValue(); } /** Stores values in the combo boxes in the component c. */ public void storeComboBoxValues(final String[] params) { for (final String param : params) { final Value value = getComboBoxValue(param); resource.get().setValue(param, value); final Widget wi = getWidget(param, null); if (wi != null) { wi.setToolTipText(getToolTipText(param, wi)); } } } /** Returns combo box for one parameter. */ protected Widget createWidget(final String param, final String prefix, final int width) { resource.get().setPossibleChoices(param, getParamPossibleChoices(param)); /* set default value */ Value initValue = getPreviouslySelected(param, prefix); if (initValue == null) { final Value value = getParamSaved(param); if (value == null || value.isNothingSelected()) { if (resource.get().isNew()) { initValue = resource.get().getPreferredValue(param); if (initValue == null) { initValue = getParamPreferred(param); } } if (initValue == null) { initValue = getParamDefault(param); resource.get().setValue(param, initValue); } } else { initValue = value; } } final String regexp = getParamRegexp(param); Map<String, String> abbreviations = new HashMap<String, String>(); if (isInteger(param)) { abbreviations = new HashMap<String, String>(); abbreviations.put("i", CrmXml.INFINITY_VALUE.getValueForConfig()); abbreviations.put("I", CrmXml.INFINITY_VALUE.getValueForConfig()); abbreviations.put("+", CrmXml.PLUS_INFINITY_VALUE.getValueForConfig()); abbreviations.put("d", CrmXml.DISABLED_IN_COMBOBOX.getValueForConfig()); abbreviations.put("D", CrmXml.DISABLED_IN_COMBOBOX.getValueForConfig()); } Widget.Type type = getFieldType(param); Unit[] units = null; if (type == Widget.Type.TEXTFIELDWITHUNIT) { units = getUnits(param); } if (isCheckBox(param)) { type = Widget.Type.CHECKBOX; } else if (isTimeType(param)) { type = Widget.Type.TEXTFIELDWITHUNIT; units = getTimeUnits(); } else if (isLabel(param)) { type = Widget.Type.LABELFIELD; } final Widget paramWi = widgetFactory.createInstance(type, initValue, getPossibleChoices(param), units, regexp, width, abbreviations, new AccessMode(getAccessType(param), isEnabledOnlyInAdvancedMode(param)), null); widgetAdd(param, prefix, paramWi); paramWi.setEditable(true); return paramWi; } /** * Checks new value of the parameter if it correct and has changed. * Returns false if parameter is invalid or has not not changed from * the stored value. This is needed to disable apply button, if some of * the values are invalid or none of the parameters have changed. */ protected abstract boolean checkParam(String param, Value newValue); /** Checks whether this value matches the regexp of this field. */ protected final boolean checkRegexp(final String param, final Value newValue) { String regexp = getParamRegexp(param); if (regexp == null) { final Widget wi = getWidget(param, null); if (wi != null) { regexp = wi.getRegexp(); } } if (regexp != null) { final Pattern p = Pattern.compile(regexp); if (newValue == null || newValue.isNothingSelected()) { return true; } final Matcher m = p.matcher(newValue.getValueForConfig()); return m.matches(); } return true; } /** * Checks parameter, but use cached value. This is useful if some other * parameter was modified, but not this one. */ protected boolean checkParamCache(final String param) { if (param == null || !paramCorrectValueMap.containsKey(param)) { return false; } final Boolean ret = paramCorrectValueMap.get(param); if (ret == null) { return false; } return ret; } /** Sets the cache for the result of the parameter check. */ protected final void setCheckParamCache(final String param, final boolean correctValue) { if (param == null) { return; } paramCorrectValueMap.put(param, correctValue); } protected abstract Value getParamDefault(String param); public Value getParamSaved(final String param) { return resource.get().getValue(param); } protected String getParamSavedForConfig(final String param) { final Value v = resource.get().getValue(param); if (v == null) { return null; } else { return v.getValueForConfig(); } } protected abstract Value getParamPreferred(String param); protected abstract String getParamShortDesc(String param); protected abstract String getParamLongDesc(String param); /** * Returns possible choices in a combo box, if possible choices are * null, instead of combo box a text field will be generated. */ protected Value[] getPossibleChoices(final String param) { return resource.get().getPossibleChoices(param); } /** * Creates panel with border and title for parameters with default * background. */ protected final JPanel getParamPanel(final String title) { return getParamPanel(title, Browser.PANEL_BACKGROUND); } /** * Creates panel with border and title for parameters with specified * background. */ protected final JPanel getParamPanel(final String title, final Color background) { final JPanel panel = new JPanel(); panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); panel.setBackground(background); final TitledBorder titleBorder = Tools.getBorder(title); panel.setBorder(titleBorder); return panel; } /** * Returns on mouse over text for parameter. If value is different * from default value, default value will be returned. */ protected final String getToolTipText(final String param, final Widget wi) { final Value defaultValue = getParamDefault(param); final StringBuilder ret = new StringBuilder(120); if (wi != null) { final String value = wi.getStringValue(); ret.append("<b>"); ret.append(value); ret.append("</b>"); } if (defaultValue != null && !defaultValue.isNothingSelected()) { ret.append("<table><tr><td><b>"); ret.append(Tools.getString("Browser.ParamDefault")); ret.append("</b></td><td>"); ret.append(defaultValue); ret.append("</td></tr></table>"); } ret.append(additionalToolTip(param)); return ret.toString(); } /** Enables and disabled apply and revert button. */ public final void setApplyButtons(final String param, final String[] params) { final Check check = checkResourceFields(param, params); swingUtils.invokeLater(new Runnable() { @Override public void run() { final MyButton ab = getApplyButton(); if (ab != null) { if (resource.isPresent() && resource.get().isNew()) { check.addChanged("new resource"); } ab.setEnabled(check); } final MyButton rb = getRevertButton(); if (rb != null) { rb.setEnabledChanged(check); } } }); } /** * Returns whether all the parameters are correct. If param is null, * all paremeters will be checked, otherwise only the param, but other * parameters will be checked only in the cache. This is good if only * one value is changed and we don't want to check everything. */ public Check checkResourceFields(final String param, final String[] params) { /* check if values are correct */ final List<String> incorrect = new ArrayList<String>(); final List<String> changed = new ArrayList<String>(); if (params != null) { for (final String otherParam : params) { final Widget wi = getWidget(otherParam, null); if (wi == null) { continue; } Value newValue = wi.getValue(); /* check if value has changed */ Value oldValue = getParamSaved(otherParam); if (oldValue == null) { oldValue = getParamDefault(otherParam); } if (!Tools.areEqual(newValue, oldValue)) { changed.add(otherParam + ": " + oldValue + " \u2192 " + newValue); } /* check correctness */ final Boolean correctValueCache = (otherParam == null) ? null : paramCorrectValueMap.get(otherParam); if (param == null || param.equals(otherParam) || correctValueCache == null) { final Widget wizardWi = getWidget(otherParam, Widget.WIZARD_PREFIX); final String enable = isEnabled(otherParam); if (wizardWi != null) { wizardWi.setDisabledReason(enable); wizardWi.setEnabled(enable == null); newValue = wizardWi.getValue(); } wi.setDisabledReason(enable); wi.setEnabled(enable == null); final boolean check = checkParam(otherParam, newValue) && checkRegexp(otherParam, newValue); if (check) { if (isTimeType(otherParam) || hasUnitPrefix(otherParam)) { wi.setBackground(getParamDefault(otherParam), getParamSaved(otherParam), isRequired(otherParam)); if (wizardWi != null) { wizardWi.setBackground(getParamDefault(otherParam), getParamSaved(otherParam), isRequired(otherParam)); } } else { wi.setBackground(getParamDefault(otherParam), getParamSaved(otherParam), isRequired(otherParam)); if (wizardWi != null) { wizardWi.setBackground(getParamDefault(otherParam), getParamSaved(otherParam), isRequired(otherParam)); } } } else { wi.wrongValue(); if (wizardWi != null) { wizardWi.wrongValue(); } incorrect.add(otherParam); } setCheckParamCache(otherParam, check); } else { if (!correctValueCache) { incorrect.add(otherParam); } } wi.processAccessMode(); } } return new Check(incorrect, changed); } /** Waits till the info panel is done for the first time. */ public final void waitForInfoPanel() { try { final boolean ret = infoPanelLatch.await(20, TimeUnit.SECONDS); if (!ret) { Tools.printStackTrace("latch timeout detected"); } infoPanelLatch.await(); } catch (final InterruptedException ignored) { Thread.currentThread().interrupt(); } } /** Should be called after info panel is done. */ protected final void infoPanelDone() { infoPanelLatch.countDown(); } public void resetInfoPanel() { infoPanelLatch = new CountDownLatch(1); } protected final void addToAdvancedList(final JPanel panel) { advancedPanelList.add(panel); } /** Hide/Show advanced panels. */ @Override public void updateAdvancedPanels() { super.updateAdvancedPanels(); final boolean advancedMode = access.isAdvancedMode(); boolean advanced = false; for (final JPanel apl : advancedPanelList) { swingUtils.invokeLater(new Runnable() { @Override public void run() { apl.setVisible(advancedMode); } }); advanced = true; } for (final String section : advancedOnlySectionList) { final JPanel p = sectionPanels.get(section, Boolean.toString(!WIZARD)); final JPanel pw = sectionPanels.get(section, Boolean.toString(WIZARD)); swingUtils.invokeLater(new Runnable() { @Override public void run() { final boolean v = advancedMode && isSectionEnabled(section); p.setVisible(v); if (pw != null) { pw.setVisible(v); } } }); advanced = true; } final boolean a = advanced; swingUtils.invokeLater(new Runnable() { @Override public void run() { moreOptionsPanel.setVisible(a && !advancedMode); } }); } /** Revert values. */ public void revert() { final String[] params = getParametersFromXML(); if (params == null) { return; } for (final String param : params) { Value v = getParamSaved(param); if (v == null) { v = getParamDefault(param); } final Widget wi = getWidget(param, null); if (wi != null && !Tools.areEqual(wi.getValue(), v)) { wi.setValue(v); final Widget wizardWi = getWidget(param, Widget.WIZARD_PREFIX); if (wizardWi != null) { wizardWi.setValue(v); } } } } public final MyButton getApplyButton() { return applyButton; } public final MyButton getRevertButton() { return revertButton; } public final void setApplyButton(final MyButton applyButton) { this.applyButton = applyButton; } public final void setRevertButton(final MyButton revertButton) { this.revertButton = revertButton; } /** Returns if dialog was started. It disables the apply button. */ private boolean isDialogStarted() { return dialogStarted; } /** Sets if dialog was started. It disables the apply button. */ public void setDialogStarted(final boolean dialogStarted) { this.dialogStarted = dialogStarted; } public void clearPanelLists() { applyButton = null; oldApplyButton = null; advancedPanelList.clear(); advancedOnlySectionList.clear(); sectionPanels.clear(); disabledSections.clear(); } @Override public final void cleanup() { super.cleanup(); clearPanelLists(); } public void reloadComboBoxes() { } /** Return previously selected value of the parameter. This is used, when * primitive changes to and from clone. */ protected final Value getPreviouslySelected(final String param, final String prefix) { final Widget prevParamWi = getWidget(param, prefix); if (prevParamWi != null) { return prevParamWi.getValue(); } return null; } protected String getSectionDisplayName(final String section) { return Tools.ucfirst(section); } protected Color getSectionColor(final String section) { return Browser.PANEL_BACKGROUND; } private JPanel getSectionPanel(final String section, final boolean wizard) { return sectionPanels.get(section, Boolean.toString(wizard)); } protected final void addSectionPanel(final String section, final boolean wizard, final JPanel sectionPanel) { sectionPanels.put(section, Boolean.toString(wizard), sectionPanel); } protected final void enableSection(final String section, final boolean enable, final boolean wizard) { if (enable) { disabledSections.remove(section); } else { disabledSections.add(section); } final JPanel p = getSectionPanel(section, wizard); if (p != null) { p.setVisible(enable); } } protected final String[] getEnabledSectionParams(final Iterable<String> params) { final List<String> newParams = new ArrayList<String>(); for (final String param : params) { if (isSectionEnabled(getSection(param))) { newParams.add(param); } } return newParams.toArray(new String[newParams.size()]); } protected final boolean isSectionEnabled(final String section) { return !disabledSections.contains(section); } protected String additionalToolTip(final String param) { return ""; } public ResourceValue getResource() { return resource.get(); } /** * This class holds a part of the panel within the same section, access * type and advanced mode setting. */ private static class PanelPart { /** Section of this panel part. */ private final String section; private final AccessMode.Type type; private final boolean advanced; PanelPart(final String section, final AccessMode.Type type, final boolean advanced) { this.section = section; this.type = type; this.advanced = advanced; } public final String getSection() { return section; } public final AccessMode.Type getType() { return type; } public final boolean isAdvanced() { return advanced; } } }