/** * Copyright (C) 2002-2012 The FreeCol Team * * This file is part of FreeCol. * * FreeCol 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 of the License, or * (at your option) any later version. * * FreeCol 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 FreeCol. If not, see <http://www.gnu.org/licenses/>. */ package net.sf.freecol.client.gui.option; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.logging.Logger; import org.freecolandroid.repackaged.java.awt.BorderLayout; import org.freecolandroid.repackaged.javax.swing.BorderFactory; import org.freecolandroid.repackaged.javax.swing.JLabel; import org.freecolandroid.repackaged.javax.swing.JPanel; import org.freecolandroid.repackaged.javax.swing.JScrollPane; import org.freecolandroid.repackaged.javax.swing.JSeparator; import org.freecolandroid.repackaged.javax.swing.JTabbedPane; import org.freecolandroid.repackaged.javax.swing.KeyStroke; import net.miginfocom.swing.MigLayout; import net.sf.freecol.client.FreeColClient; import net.sf.freecol.client.gui.GUI; import net.sf.freecol.client.gui.i18n.Messages; import net.sf.freecol.common.model.FreeColObject; import net.sf.freecol.common.option.Option; import net.sf.freecol.common.option.OptionGroup; /** * This class provides visualization for an {@link * net.sf.freecol.common.option.OptionGroup}. In order to enable values * to be both seen and changed. */ public final class OptionGroupUI extends JPanel implements OptionUpdater { private static final Logger logger = Logger.getLogger(OptionGroupUI.class.getName()); public static final int H_GAP = 10; private final List<OptionUpdater> optionUpdaters = new ArrayList<OptionUpdater>(); private final HashMap<String, OptionUI> optionUIs; private final JTabbedPane tb; private GUI gui; private FreeColClient freeColClient; /** * Creates a new <code>OptionGroupUI</code> for the given * <code>OptionGroup</code>. This is the same as using * {@link #OptionGroupUI(OptionGroup, boolean)} with * <code>editable == true</code>. * * @param option The <code>OptionGroup</code> to make a user interface for. */ public OptionGroupUI(FreeColClient freeColClient, GUI gui, OptionGroup option) { this(freeColClient, gui, option, true); } /** * Creates a new <code>OptionGroupUI</code> for the given * <code>OptionGroup</code>. * * @param option The <code>OptionGroup</code> to make a user interface for * @param editable boolean whether user can modify the setting */ public OptionGroupUI(FreeColClient freeColClient, GUI gui, OptionGroup option, boolean editable) { super(new BorderLayout()); this.gui = gui; this.freeColClient = freeColClient; JPanel northPanel = new JPanel(); northPanel.setLayout(new MigLayout("wrap 4", "[fill]related[fill]unrelated[fill]related[fill]")); northPanel.setOpaque(false); optionUIs = new HashMap<String, OptionUI>(); tb = new JTabbedPane(JTabbedPane.TOP); tb.setOpaque(false); Iterator<Option> it = option.iterator(); while (it.hasNext()) { Option o = it.next(); if (o instanceof OptionGroup) { OptionGroup group = (OptionGroup) o; JPanel groupPanel = new JPanel(); groupPanel.setLayout(new MigLayout("wrap 4", "[fill]related[fill]unrelated[fill]related[fill]")); groupPanel.setOpaque(true); addOptionGroupUI(group, groupPanel, editable); JScrollPane scroll = new JScrollPane(groupPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scroll.getVerticalScrollBar().setUnitIncrement(16); scroll.setBorder(BorderFactory.createEmptyBorder()); groupPanel.setBorder(BorderFactory.createEmptyBorder(H_GAP - 5, H_GAP, 0, H_GAP)); tb.addTab(Messages.getName((Option) group), null, scroll, Messages.getShortDescription((Option) group)); } else { addOptionUI(o, northPanel, editable); } } if (tb.getTabCount() > 0) { /** ignore options that do not belong to an OptionGroup, e.g. window sizes and positions if (northPanel.getComponentCount() > 0) { tb.addTab(" *** ", northPanel); } */ add(tb, BorderLayout.CENTER); } else { add(northPanel, BorderLayout.CENTER); } setOpaque(false); } private void addOptionGroupUI(OptionGroup group, JPanel panel, boolean editable) { Iterator<Option> iterator = group.iterator(); while (iterator.hasNext()) { Option o = iterator.next(); if (o instanceof OptionGroup) { OptionGroup subgroup = (OptionGroup) o; panel.add(new JLabel(Messages.getName((Option) subgroup)), "newline 20, span, split 2"); panel.add(new JSeparator(), "growx"); addOptionGroupUI(subgroup, panel, editable); } else { addOptionUI(o, panel, editable); } } } private void addOptionUI(Option option, JPanel panel, boolean editable) { OptionUI ui = OptionUI.getOptionUI(freeColClient, gui, option, editable); if (ui == null) { logger.warning("Unknown option type: " + option.toString()); } else if (ui instanceof FreeColActionUI) { ((FreeColActionUI) ui).setOptionGroupUI(this); } JLabel label = ui.getLabel(); if (label == null) { panel.add(ui.getComponent(), "newline, span"); } else { if (label.getText().length() > 30) { panel.add(label, "newline, span 3"); } else { panel.add(label); } panel.add(ui.getComponent()); } if (editable) { optionUpdaters.add((OptionUpdater) ui); } //FIXME Patched this to handle AudioMixer not working if (option != null && option.getId() != null && !option.getId().equals(FreeColObject.NO_ID)) { optionUIs.put(option.getId(), ui); } } /** * Updates the value of the {@link net.sf.freecol.common.option.Option} this object keeps. */ public void updateOption() { for (OptionUpdater optionUpdater : optionUpdaters) { optionUpdater.updateOption(); } } public OptionUI getOptionUI(String key) { return optionUIs.get(key); } /** * Removes the given <code>KeyStroke</code> from all of this * <code>OptionGroupUI</code>'s children. * * @param keyStroke The <code>KeyStroke</code> to be removed. */ public void removeKeyStroke(KeyStroke keyStroke) { for (OptionUpdater optionUpdater : optionUpdaters) { if (optionUpdater instanceof FreeColActionUI) { ((FreeColActionUI) optionUpdater).removeKeyStroke(keyStroke); } } } /** * Reset with the value from the option. */ public void reset() { for (OptionUpdater optionUpdater : optionUpdaters) { optionUpdater.reset(); } } @Override public String getUIClassID() { return "ReportPanelUI"; } }