Gridarta Editor
MaskChangeAL.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2015 The Gridarta Developers.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package net.sf.gridarta.gui.dialog.gameobjectattributes;
21 
22 import java.awt.Container;
23 import java.awt.GridLayout;
24 import java.awt.event.ActionEvent;
25 import javax.swing.AbstractAction;
26 import javax.swing.JCheckBox;
27 import javax.swing.JOptionPane;
28 import javax.swing.JPanel;
29 import javax.swing.event.ChangeEvent;
30 import javax.swing.event.ChangeListener;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40 
45 public class MaskChangeAL<G extends GameObject<G, A, R>, A extends MapArchObject<A>, R extends Archetype<G, A, R>> extends AbstractAction {
46 
50  private static final long serialVersionUID = 1L;
51 
55  @NotNull
57 
61  @NotNull
63 
67  @NotNull
68  private final JCheckBox[] checkbox;
69 
73  @NotNull
74  private final Container gridPanel;
75 
79  @NotNull
80  private final ChangeListener singleChangeListener = new ChangeListener() {
81 
82  @Override
83  public void stateChanged(final ChangeEvent e) {
85  }
86  };
87 
91  @NotNull
92  private final ChangeListener allChangeListener = new ChangeListener() {
93 
94  @Override
95  public void stateChanged(final ChangeEvent e) {
96  switch (allCheckbox.getTristateModel().getTristateState()) {
97  case DESELECTED:
98  setAllBits(false);
99  break;
100 
101  case INDETERMINATE:
102  // ignore
103  break;
104 
105  case SELECTED:
106  setAllBits(true);
107  break;
108  }
109  }
110  };
111 
118  public MaskChangeAL(@NotNull final String label, @NotNull final DialogAttributeBitmask<G, A, R> dialogAttributeBitmask) {
119  super(label);
120  this.dialogAttributeBitmask = dialogAttributeBitmask;
121 
122  gridPanel = new JPanel(new GridLayout(0, 2, 3, 3));
123  final AttributeBitmask attributeBitmask = dialogAttributeBitmask.getBitmask();
124  final int number = attributeBitmask.getNumber();
125  final int value = dialogAttributeBitmask.getValue();
126  checkbox = new JCheckBox[number];
127  for (int i = 0; i < number; i++) {
128  final String name = attributeBitmask.getBitName(i);
129  if (name != null) {
130  checkbox[i] = new JCheckBox(name);
131  checkbox[i].addChangeListener(singleChangeListener);
132  checkbox[i].setSelected(isActive(i + 1, value));
133  gridPanel.add(checkbox[i]);
134  }
135  }
136  if (gridPanel.getComponentCount() % 2 != 0) {
137  gridPanel.add(new JPanel());
138  }
139  allCheckbox = new ToggleTristateCheckBox("All"); // TODO: I18N/L10N
140  allCheckbox.addChangeListener(allChangeListener);
141  gridPanel.add(allCheckbox);
142  }
143 
144  @Override
145  public void actionPerformed(@NotNull final ActionEvent e) {
146  final Integer newValue = showBitmaskDialog();
147  if (newValue != null) {
148  dialogAttributeBitmask.setValue(newValue);
149  }
150  }
151 
152  @NotNull
153  @Override
154  protected Object clone() {
155  try {
156  return super.clone();
157  } catch (final CloneNotSupportedException ex) {
158  throw new AssertionError(ex);
159  }
160  }
161 
167  @Nullable
168  private Integer showBitmaskDialog() {
169  setValue();
170  final String attributeName = dialogAttributeBitmask.getRef().getAttributeName();
171  final String title = "Choose " + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
172  if (JOptionPane.showConfirmDialog(dialogAttributeBitmask.getInput(), gridPanel, title, JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) {
173  return getValue();
174  }
175  return null;
176  }
177 
182  private int getValue() {
183  final AttributeBitmask attributeBitmask = dialogAttributeBitmask.getBitmask();
184  final int number = attributeBitmask.getNumber();
185  int newValue = 0;
186  for (int i = 0; i < number; i++) {
187  if (checkbox[i] != null && checkbox[i].isSelected()) {
188  newValue |= 1 << i;
189  }
190  }
191  return newValue;
192  }
193 
197  private void setValue() {
198  final int value = dialogAttributeBitmask.getValue();
199  final int number = dialogAttributeBitmask.getBitmask().getNumber();
200  for (int i = 0; i < number; i++) {
201  if (checkbox[i] != null) {
202  checkbox[i].setSelected(isActive(i + 1, value));
203  }
204  }
205  }
206 
211  private void setAllBits(final boolean state) {
212  final AttributeBitmask attributeBitmask = dialogAttributeBitmask.getBitmask();
213  final int number = attributeBitmask.getNumber();
214  for (int i = 0; i < number; i++) {
215  if (checkbox[i] != null) {
216  checkbox[i].setSelected(state);
217  }
218  }
219  }
220 
226  @NotNull
228  final AttributeBitmask attributeBitmask = dialogAttributeBitmask.getBitmask();
229  final int number = attributeBitmask.getNumber();
230  int i;
231  for (i = 0; i < number; i++) {
232  if (checkbox[i] != null) {
233  break;
234  }
235  }
236  if (i >= number) {
237  return TristateState.DESELECTED;
238  }
239  final boolean state = checkbox[i++].isSelected();
240  while (i < number) {
241  if (checkbox[i] != null && checkbox[i].isSelected() != state) {
242  return TristateState.INDETERMINATE;
243  }
244  i++;
245  }
246  return TristateState.getTristateState(state);
247  }
248 
256  private static boolean isActive(final int index, final int mask) {
257  final int bit = 1 << (index - 1);
258  return (mask & bit) == bit;
259  }
260 
261 }
final JCheckBox [] checkbox
The single-bit check boxes.
final DialogAttributeBitmask< G, A, R > dialogAttributeBitmask
The DialogAttributeBitmask where this change button belongs to.
A TristateCheckBox that skips the indeterminate state when activated.
void setAllBits(final boolean state)
Sets all bit-value check boxes to the given state.
MaskChangeAL(@NotNull final String label, @NotNull final DialogAttributeBitmask< G, A, R > dialogAttributeBitmask)
Constructor.
Graphical User Interface of Gridarta.
TristateState getTristateState()
Returns the internal state.
String getBitName(final int index)
Returns the name of a bitmask value.
Implements TristateCheckBox, a JCheckBox variant that supports three states: deselected, indeterminate, selected.
TristateButtonModel getTristateModel()
Returns the model as a TristateButtonModel.
static boolean isActive(final int index, final int mask)
Check whether the given bit-index is an active bit in the bitmask.
final Container gridPanel
The top-level container of the dialog.
static final long serialVersionUID
The serial version UID.
int getValue()
Returns the currently selected values.
A JCheckBox that supports three states: deselected, indeterminate, selected.
Base package of all Gridarta classes.
final ChangeListener singleChangeListener
The ChangeListener attached to all single-bit check boxes.
Reflects a game object (object on a map).
Definition: GameObject.java:36
int getNumber()
Returns the number of bitmask entries (not counting zero).
final void setTristateState(@NotNull final TristateState state)
Sets the state.
Possible states for TristateButtonModels.
GameObjects are the objects based on Archetypes found on maps.
This class manages bitmask values which appear in Gridarta archetype attributes.
void setValue()
Sets the currently selected values to the default values.
Component getInput()
Returns the input ui component for editing the value.
final TristateCheckBox allCheckbox
The all-bits check box.
final ChangeListener allChangeListener
The ChangeListener attached to the "All" check box.
TristateState getBitState()
Returns the TristateState that reflects the current state of all bit-value check boxes.
Integer showBitmaskDialog()
Open a popup frame to select bitmask-entries via choose boxes.
ActionListener for the change buttons of bitmasks.
static TristateState getTristateState(final boolean state)
Returns the tristate state for a boolean state.
Defines types of GameObjects with corresponding attributes.