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.gui.resources; import lcmc.gui.Browser; import lcmc.gui.Widget; import lcmc.utilities.ButtonCallback; import lcmc.utilities.MyButton; import lcmc.utilities.Tools; import lcmc.utilities.Unit; import lcmc.utilities.WidgetListener; import lcmc.data.CRMXML; import lcmc.data.ConfigData; import lcmc.data.AccessMode; import lcmc.data.resources.Resource; import lcmc.gui.SpringUtilities; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.border.TitledBorder; import javax.swing.SpringLayout; import javax.swing.BoxLayout; import java.util.Map; import java.util.HashMap; import java.util.concurrent.CountDownLatch; import java.util.List; import java.util.ArrayList; import java.util.Set; import java.util.HashSet; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.awt.Color; import java.awt.Font; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import org.apache.commons.collections15.map.MultiKeyMap; import java.util.concurrent.TimeUnit; /** * This class provides textfields, combo boxes etc. for editable info * objects. */ public abstract class EditableInfo extends Info { /** Hash from parameter to boolean value if the last entered value was * correct. */ private final Map<String, Boolean> paramCorrectValueMap = new HashMap<String, Boolean>(); /** Returns section in which is this parameter. */ protected abstract String getSection(String param); /** Returns whether this parameter is required. */ protected abstract boolean isRequired(String param); /** Returns whether this parameter is advanced. */ 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); /** Returns access type of this parameter. */ protected abstract ConfigData.AccessType getAccessType(String param); /** Returns whether this parameter is enabled in advanced mode. */ protected abstract boolean isEnabledOnlyInAdvancedMode(String param); /** Returns whether this parameter is of label type. */ protected abstract boolean isLabel(String param); /** Returns whether this parameter is of the integer type. */ protected abstract boolean isInteger(String param); /** Returns whether this parameter is of the time type. */ protected abstract boolean isTimeType(String param); /** Returns whether this parameter has a unit prefix. */ protected boolean hasUnitPrefix(final String param) { return false; } /** Returns whether this parameter is of the check box type, like * boolean. */ protected abstract boolean isCheckBox(String param); /** Returns type of the field. */ protected Widget.Type getFieldType(final String param) { return null; } /** Returns the name of the type. */ protected abstract String getParamType(final String param); /** Returns the regexp of the parameter. */ protected String getParamRegexp(final String param) { // TODO: this should be only for Pacemaker if (isInteger(param)) { return "^((-?\\d*|(-|\\+)?" + CRMXML.INFINITY_STRING + "|" + CRMXML.DISABLED_STRING + "))|@NOTHING_SELECTED@$"; } return null; } /** Returns the possible choices for pull down menus if applicable. */ protected abstract Object[] getParamPossibleChoices(String param); /** Returns array of all parameters. */ public abstract String[] getParametersFromXML(); // TODO: no XML /** Old apply button, is used for wizards. */ private MyButton oldApplyButton = null; /** Apply button. */ private MyButton applyButton; /** Revert button. */ private MyButton revertButton; /** Is counted down, first time the info panel is initialized. */ private final CountDownLatch infoPanelLatch = new CountDownLatch(1); /** List of advanced panels. */ private final List<JPanel> advancedPanelList = new ArrayList<JPanel>(); /** List of messages if advanced panels are hidden. */ private final List<JPanel> advancedOnlySectionList = new ArrayList<JPanel>(); /** More options panel. */ private final JPanel moreOptionsPanel = new JPanel(); /** Whether dialog was started. It disables the apply button. */ private boolean dialogStarted = false; /** How much of the info is used. */ public int getUsed() { return -1; } /** * Prepares a new <code>EditableInfo</code> object. * * @param name * name that will be shown to the user. */ EditableInfo(final String name, final Browser browser) { super(name, browser); } /** Inits apply button. */ final void initApplyButton(final ButtonCallback buttonCallback) { initApplyButton(buttonCallback, Tools.getString("Browser.ApplyResource")); } /** Inits commit button. */ final void initCommitButton(final ButtonCallback buttonCallback) { initApplyButton(buttonCallback, Tools.getString("Browser.CommitResources")); } /** Inits apply or commit button button. */ final void initApplyButton(final ButtonCallback buttonCallback, final String text) { if (oldApplyButton == null) { applyButton = new MyButton(text, Browser.APPLY_ICON); applyButton.miniButton(); applyButton.setEnabled(false); oldApplyButton = applyButton; revertButton = new MyButton(Tools.getString("Browser.RevertResource"), Browser.REVERT_ICON); revertButton.setEnabled(false); revertButton.setToolTipText(Tools.getString("Browser.RevertResource.ToolTip")); revertButton.miniButton(); 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.WEST); Tools.getGUIData().getMainFrameRootPane().setDefaultButton(applyButton); } /** Creates revert button and adds it to the panel. */ protected final void addRevertButton(final JPanel panel) { final JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT, 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 JComponent left, final JComponent right, final int leftWidth, final int rightWidth, int height) { /* right component with fixed width. */ if (height == 0) { height = Tools.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, "wizard", params, wizardApplyButton, leftWidth, rightWidth, sameAsFields); } /** * 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; /** Access type of this panel part. */ private final ConfigData.AccessType accessType; /** Whether it is an advanced panel part. */ private final boolean advanced; /** Creates new panel part object. */ public PanelPart(final String section, final ConfigData.AccessType accessType, final boolean advanced) { this.section = section; this.accessType = accessType; this.advanced = advanced; } /** Returns a section to which this panel part belongs. */ public final String getSection() { return section; } /** Returns access type of this panel part. */ public final ConfigData.AccessType getAccessType() { return accessType; } /** Whether this panel part has advanced options. */ public final boolean isAdvanced() { return advanced; } } /** 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) { if (params == null) { return; } final MultiKeyMap<String, JPanel> panelPartsMap = new MultiKeyMap<String, JPanel>(); final List<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); JPanel panel; final ConfigData.AccessType 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(Browser.PANEL_BACKGROUND); if (advanced) { advancedPanelList.add(panel); final JPanel p = panel; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { p.setVisible(Tools.getConfigData().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 */ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { paramWi.setToolTipText(getToolTipText(param)); label.setToolTipText(longDesc); } }); int height = 0; if (paramWi.getType() == Widget.Type.LABELFIELD) { height = Tools.getDefaultSize("Browser.LabelFieldHeight"); } addField(panel, label, paramWi, leftWidth, rightWidth, height); } for (final String param : params) { final Widget paramWi = getWidget(param, prefix); Widget rpwi = null; if ("wizard".equals(prefix)) { rpwi = getWidget(param, null); if (rpwi == null) { Tools.appError("unkown param: " + param + ". Man pages not installed?"); continue; } int height = 0; if (rpwi.getType() == Widget.Type.LABELFIELD) { height = Tools.getDefaultSize("Browser.LabelFieldHeight"); } final Widget rpwi0 = rpwi; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (paramWi.getValue() == null || paramWi.getValue() == Widget.NOTHING_SELECTED) { rpwi0.setValueAndWait(null); } else { final Object value = paramWi.getStringValue(); rpwi0.setValueAndWait(value); } } }); } } for (final String param : params) { final Widget paramWi = getWidget(param, prefix); Widget rpwi = null; if ("wizard".equals(prefix)) { rpwi = getWidget(param, null); } final Widget realParamWi = rpwi; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { paramWi.addListeners(new WidgetListener() { @Override public void check(final Object value) { checkParameterFields(paramWi, realParamWi, param, params, thisApplyButton); } }); } }); } /* add sub panels to the option panel */ final Map<String, JPanel> sectionMap = new HashMap<String, JPanel>(); final Set<JPanel> notAdvancedSections = new HashSet<JPanel>(); final Set<JPanel> advancedSections = new HashSet<JPanel>(); for (final PanelPart panelPart : panelPartsList) { final String section = panelPart.getSection(); final ConfigData.AccessType accessType = panelPart.getAccessType(); 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 JPanel sectionPanel; if (sectionMap.containsKey(section)) { sectionPanel = sectionMap.get(section); } else { sectionPanel = getParamPanel(section); sectionMap.put(section, 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("Same As"); sameAsCombo.setLabel(label, ""); addField(saPanel, label, sameAsCombo, leftWidth, rightWidth, 0); SpringUtilities.makeCompactGrid(saPanel, 1, 2, 1, 1, // initX, initY 1, 1); // xPad, yPad sectionPanel.add(saPanel); } } } sectionPanel.add(panel); if (advanced) { advancedSections.add(sectionPanel); } else { notAdvancedSections.add(sectionPanel); } } boolean advanced = false; for (final JPanel sectionPanel : sectionMap.values()) { if (advancedSections.contains(sectionPanel)) { advanced = true; } if (!notAdvancedSections.contains(sectionPanel)) { advancedOnlySectionList.add(sectionPanel); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { sectionPanel.setVisible(Tools.getConfigData().isAdvancedMode()); } }); } } final boolean a = advanced; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { moreOptionsPanel.setVisible(a && !Tools.getConfigData().isAdvancedMode()); } }); } /** Returns a more panel with "more options are available" message. */ protected 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 EditableInfo thisClass = this; final Thread thread = new Thread(new Runnable() { @Override public void run() { //SwingUtilities.invokeLater(new Runnable() { // @Override // public void run() { // paramWi.setEditable(); // } //}); boolean c; boolean ch = false; if (realParamWi == null) { Tools.waitForSwing(); ch = checkResourceFieldsChanged(param, params); c = checkResourceFieldsCorrect(param, params); } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (paramWi.getValue() == null || paramWi.getValue() == Widget.NOTHING_SELECTED) { realParamWi.setValueAndWait(null); } else { final Object value = paramWi.getStringValue(); realParamWi.setValueAndWait(value); } } }); Tools.waitForSwing(); c = checkResourceFieldsCorrect(param, params); } final boolean check = c; final boolean changed = ch; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if (thisApplyButton == applyButton) { thisApplyButton .setEnabled(!isDialogStarted() && check && (changed || getResource().isNew())); } else { /* wizard button */ thisApplyButton.setEnabled(check); } if (revertButton != null) { revertButton.setEnabled(changed); } paramWi.setToolTipText(getToolTipText(param)); if (realParamWi != null) { realParamWi.setToolTipText(getToolTipText(param)); } } }); } }); thread.start(); } /** Get stored value in the combo box. */ public final String getComboBoxValue(final String param) { final Widget wi = getWidget(param, null); if (wi == null) { return null; } final Object o = wi.getValue(); String value; if (Tools.isStringClass(o)) { value = wi.getStringValue(); } else if (o instanceof Object[]) { value = ((Object[]) o)[0].toString(); if (((Object[]) o)[1] instanceof Unit) { value += ((Unit) ((Object[]) o)[1]).getShortName(); } } else { value = ((Info) o).getStringValue(); } return value; } /** Stores values in the combo boxes in the component c. */ protected void storeComboBoxValues(final String[] params) { for (String param : params) { final String value = getComboBoxValue(param); getResource().setValue(param, value); final Widget wi = getWidget(param, null); if (wi != null) { wi.setToolTipText(getToolTipText(param)); } } } /** Returns combo box for one parameter. */ protected Widget createWidget(final String param, final String prefix, final int width) { getResource().setPossibleChoices(param, getParamPossibleChoices(param)); /* set default value */ String initValue = getPreviouslySelected(param, prefix); if (initValue == null) { final String value = getParamSaved(param); if (value == null || "".equals(value)) { if (getResource().isNew()) { initValue = getResource().getPreferredValue(param); if (initValue == null) { initValue = getParamPreferred(param); } } if (initValue == null) { initValue = getParamDefault(param); getResource().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_STRING); abbreviations.put("I", CRMXML.INFINITY_STRING); abbreviations.put("+", CRMXML.PLUS_INFINITY_STRING); abbreviations.put("d", CRMXML.DISABLED_STRING); abbreviations.put("D", CRMXML.DISABLED_STRING); } Widget.Type type = getFieldType(param); Unit[] units = null; if (type == Widget.Type.TEXTFIELDWITHUNIT) { units = getUnits(); } 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 = new Widget(initValue, getPossibleChoices(param), units, type, regexp, width, abbreviations, new AccessMode(getAccessType(param), isEnabledOnlyInAdvancedMode(param))); 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, String newValue); /** Checks whether this value matches the regexp of this field. */ protected final boolean checkRegexp(final String param, final String 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); final Matcher m = p.matcher(newValue); if (m.matches()) { return true; } return false; } 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 (!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) { paramCorrectValueMap.put(param, correctValue); } /** Returns default value of a parameter. */ protected abstract String getParamDefault(String param); /** Returns saved value of a parameter. */ protected String getParamSaved(final String param) { return getResource().getValue(param); } /** Returns preferred value of a parameter. */ protected abstract String getParamPreferred(String param); /** Returns short description of a parameter. */ protected abstract String getParamShortDesc(String param); /** Returns long description of a parameter. */ 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 Object[] getPossibleChoices(final String param) { return getResource().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.Y_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 String defaultValue = getParamDefault(param); final StringBuilder ret = new StringBuilder(120); final Widget wi = getWidget(param, null); if (wi != null) { final Object value = wi.getStringValue(); ret.append("<b>"); ret.append(value); ret.append("</b>"); } if (defaultValue != null && !defaultValue.equals("")) { 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>"); } return ret.toString(); } /** Enables and disabled apply and revert button. */ public final void setApplyButtons(final String param, final String[] params) { final boolean ch = checkResourceFieldsChanged(param, params); final boolean cor = checkResourceFieldsCorrect(param, params); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { final MyButton ab = getApplyButton(); final Resource r = getResource(); if (ab != null) { ab.setEnabled((ch || (r != null && r.isNew())) && cor); } final MyButton rb = getRevertButton(); if (rb != null) { rb.setEnabled(ch); } } }); } ///** // * Can be called from dialog box, where it does not need to check if // * fields have changed. // */ //public boolean checkResourceFields(final String param, // final String[] params) { // final boolean cor = checkResourceFieldsCorrect(param, params); // final boolean changed = checkResourceFieldsChanged(param, params); // if (cor) { // return changed; // } // return cor; //} /** Checks one parameter. */ protected void checkOneParam(final String param) { checkResourceFieldsCorrect(param, new String[] { param }); } /** * 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. */ boolean checkResourceFieldsCorrect(final String param, final String[] params) { /* check if values are correct */ boolean correctValue = true; if (params != null) { for (final String otherParam : params) { final Widget wi = getWidget(otherParam, null); if (wi == null) { continue; } String newValue; final Object o = wi.getValue(); if (Tools.isStringClass(o)) { newValue = wi.getStringValue(); } else if (o instanceof Object[]) { final Object o0 = ((Object[]) o)[0]; final Object o1 = ((Object[]) o)[1]; newValue = o0.toString(); if (o1 != null && o1 instanceof Unit) { newValue += ((Unit) o1).getShortName(); } } else { newValue = ((Info) o).getStringValue(); } if (param == null || otherParam.equals(param) || !paramCorrectValueMap.containsKey(param)) { final Widget wizardWi = getWidget(otherParam, "wizard"); final String enable = isEnabled(otherParam); if (wizardWi != null) { wizardWi.setDisabledReason(enable); wizardWi.setEnabled(enable == null); final Object wo = wizardWi.getValue(); if (Tools.isStringClass(wo)) { newValue = wizardWi.getStringValue(); } else if (wo instanceof Object[]) { newValue = ((Object[]) wo)[0].toString() + ((Unit) ((Object[]) wo)[1]).getShortName(); } else { newValue = ((Info) wo).getStringValue(); } } 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(Tools.extractUnit(getParamDefault(otherParam)), Tools.extractUnit(getParamSaved(otherParam)), isRequired(otherParam)); if (wizardWi != null) { wizardWi.setBackground(Tools.extractUnit(getParamDefault(otherParam)), Tools.extractUnit(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(); } correctValue = false; } setCheckParamCache(otherParam, check); } else { correctValue = correctValue && checkParamCache(otherParam); } } } return correctValue; } /** * Returns whetherrs the specified parameter or any of the parameters * have changed. If param is null, only param will be checked, * otherwise all parameters will be checked. */ boolean checkResourceFieldsChanged(final String param, final String[] params) { /* check if something is different from saved values */ boolean changedValue = false; if (params != null) { for (String otherParam : params) { final Widget wi = getWidget(otherParam, null); if (wi == null) { continue; } final Object newValue = wi.getValue(); /* check if value has changed */ Object oldValue = getParamSaved(otherParam); if (oldValue == null) { oldValue = getParamDefault(otherParam); } if (isTimeType(otherParam) || hasUnitPrefix(otherParam)) { oldValue = Tools.extractUnit((String) oldValue); } if (!Tools.areEqual(newValue, oldValue)) { changedValue = true; } wi.processAccessMode(); } } return changedValue; } /** Return JLabel object for the combobox. */ protected final JLabel getLabel(final Widget wi) { return wi.getLabel(); } /** Waits till the info panel is done for the first time. */ public final void waitForInfoPanel() { try { boolean ret = infoPanelLatch.await(20, TimeUnit.SECONDS); if (!ret) { Tools.printStackTrace("latch timeout detected"); } infoPanelLatch.await(); } catch (InterruptedException ignored) { Thread.currentThread().interrupt(); } } /** Should be called after info panel is done. */ final void infoPanelDone() { infoPanelLatch.countDown(); } /** Adds a panel to the advanced list. */ protected final void addToAdvancedList(final JPanel p) { advancedPanelList.add(p); } /** Hide/Show advanced panels. */ @Override public void updateAdvancedPanels() { super.updateAdvancedPanels(); final boolean advancedMode = Tools.getConfigData().isAdvancedMode(); boolean advanced = false; for (final JPanel apl : advancedPanelList) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { apl.setVisible(advancedMode); } }); advanced = true; } for (final JPanel p : advancedOnlySectionList) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { p.setVisible(advancedMode); } }); advanced = true; } final boolean a = advanced; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { moreOptionsPanel.setVisible(a && !advancedMode); } }); } /** Revert valus. */ public void revert() { final String[] params = getParametersFromXML(); if (params == null) { return; } for (final String param : params) { String v = getParamSaved(param); if (v == null) { v = getParamDefault(param); } final Widget wi = getWidget(param, null); if (wi != null && !Tools.areEqual(wi.getStringValue(), v)) { wi.setValue(v); final Widget wizardWi = getWidget(param, "wizard"); if (wizardWi != null) { wizardWi.setValue(v); } } } } /** Returns apply button. */ final MyButton getApplyButton() { return applyButton; } /** Returns revert button. */ final MyButton getRevertButton() { return revertButton; } /** Sets apply button. */ final void setApplyButton(final MyButton applyButton) { this.applyButton = applyButton; } /** Sets revert button. */ 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; } /** Clear panel lists. */ protected void clearPanelLists() { advancedPanelList.clear(); advancedOnlySectionList.clear(); } /** Cleanup. */ final void cleanup() { super.cleanup(); clearPanelLists(); } /** Reload combo boxes. */ public void reloadComboBoxes() { } /** Return previously selected value of the parameter. This is used, when * primitive changes to and from clone. */ protected final String getPreviouslySelected(final String param, final String prefix) { final Widget prevParamWi = getWidget(param, prefix); if (prevParamWi != null) { return prevParamWi.getStringValue(); } return null; } }