001/* 002 * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games. 003 * Copyright (C) 2000-2011 The Gridarta Developers. 004 * 005 * This program is free software; you can redistribute it and/or modify 006 * it under the terms of the GNU General Public License as published by 007 * the Free Software Foundation; either version 2 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License along 016 * with this program; if not, write to the Free Software Foundation, Inc., 017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 018 */ 019 020package net.sf.gridarta.gui.dialog.plugin.parameter; 021 022import java.awt.Component; 023import java.awt.event.ActionEvent; 024import java.awt.event.ActionListener; 025import javax.swing.AbstractButton; 026import javax.swing.JButton; 027import javax.swing.JComponent; 028import javax.swing.JOptionPane; 029import javax.swing.JSpinner; 030import javax.swing.SpinnerModel; 031import javax.swing.SpinnerNumberModel; 032import javax.swing.event.ChangeEvent; 033import javax.swing.event.ChangeListener; 034import net.sf.gridarta.model.archetype.Archetype; 035import net.sf.gridarta.model.gameobject.GameObject; 036import net.sf.gridarta.model.maparchobject.MapArchObject; 037import net.sf.gridarta.plugin.parameter.DoubleParameter; 038import org.jetbrains.annotations.NotNull; 039import org.jetbrains.annotations.Nullable; 040 041public class DoubleParameterView<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> implements PluginParameterView<G, A, R>, ActionListener { 042 043 @NotNull 044 private final JSpinner value; 045 046 @NotNull 047 private final AbstractButton config; 048 049 @NotNull 050 private final DoubleParameter<G, A, R> parameter; 051 052 public DoubleParameterView(@NotNull final DoubleParameter<G, A, R> param) { 053 parameter = param; 054 final SpinnerModel mdl = new SpinnerNumberModel(0.0, param.getMin(), param.getMax(), (param.getMax() - param.getMin()) / 100.0); 055 value = new TooltipSpinner(mdl); 056 try { 057 value.setValue(param.getValue()); 058 } catch (final IllegalArgumentException e) { 059 } 060 value.addChangeListener(new ChangeListener() { 061 062 @Override 063 public void stateChanged(final ChangeEvent e) { 064 parameter.setValue((Double) ((SpinnerNumberModel) value.getModel()).getNumber()); 065 } 066 }); 067 config = new JButton("..."); 068 config.setBorderPainted(false); 069 config.setActionCommand("Config"); 070 config.addActionListener(this); 071 updateTooltip(); 072 } 073 074 @NotNull 075 @Override 076 public JComponent getConfigComponent() { 077 return config; 078 } 079 080 @NotNull 081 @Override 082 public JComponent getValueComponent() { 083 return value; 084 } 085 086 private void updateTooltip() { 087 final String toolTip = "[" + Double.toString(parameter.getMin()) + "," + Double.toString(parameter.getMax()) + "]"; 088 config.setToolTipText(toolTip); 089 value.setToolTipText(toolTip); 090 } 091 092 @Override 093 public void actionPerformed(@NotNull final ActionEvent e) { 094 if (e.getActionCommand().equals("Config")) { 095 final String min = JOptionPane.showInputDialog("Minimum value:", parameter.getMin()); 096 final String max = JOptionPane.showInputDialog("Maximum value:", parameter.getMax()); 097 try { 098 parameter.setMax(Double.parseDouble(max)); 099 parameter.setMin(Double.parseDouble(min)); 100 ((SpinnerNumberModel) value.getModel()).setMinimum(parameter.getMin()); 101 ((SpinnerNumberModel) value.getModel()).setMaximum(parameter.getMax()); 102 updateTooltip(); 103 } catch (final Exception ex) { 104 JOptionPane.showMessageDialog(null, "Could not change Double configuration"); 105 } 106 } 107 } 108 109 /** 110 * Extends JSpinner to work around it's tooltip bug This bug has been fixed 111 * since Java 5.0 but we need this workaround for java 4.x users. 112 * @author tchize 113 */ 114 private static class TooltipSpinner extends JSpinner { 115 116 private static final long serialVersionUID = 1L; 117 118 private TooltipSpinner(@NotNull final SpinnerModel model) { 119 super(model); 120 } 121 122 /** 123 * This override the JSpinner method to force the tooltip in all 124 * sub-components. 125 * @param text the tooltip to show 126 */ 127 @Override 128 public void setToolTipText(@Nullable final String text) { 129 forceTooltip(this, text); 130 } 131 132 private void forceTooltip(@NotNull final JComponent c, @Nullable final String tip) { 133 if (c == this) { 134 super.setToolTipText(tip); 135 } else { 136 c.setToolTipText(tip); 137 } 138 final Component[] components = c.getComponents(); 139 for (final Component component : components) { 140 if (component instanceof JComponent) { 141 forceTooltip((JComponent) component, tip); 142 } 143 } 144 } 145 146 } 147 148}