Gridarta Editor
TabbedPanel.java
Go to the documentation of this file.
1 /*
2  * Gridarta MMORPG map editor for Crossfire, Daimonin and similar games.
3  * Copyright (C) 2000-2023 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.utils.tabbedpanel;
21 
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Container;
25 import java.util.IdentityHashMap;
26 import java.util.Map;
27 import java.util.prefs.Preferences;
28 import javax.swing.JMenu;
29 import javax.swing.JPopupMenu;
30 import net.sf.gridarta.MainControl;
35 import net.sf.japi.swing.action.ActionBuilder;
36 import net.sf.japi.swing.action.ActionBuilderFactory;
37 import net.sf.japi.swing.action.ToggleAction;
38 import org.jetbrains.annotations.NotNull;
39 import org.jetbrains.annotations.Nullable;
40 
47 public class TabbedPanel extends Container {
48 
52  @NotNull
53  private static final String TAB_PREFIX = "MainWindow.tab";
54 
58  private static final long serialVersionUID = 1L;
59 
63  @NotNull
64  private static final ActionBuilder ACTION_BUILDER = ActionBuilderFactory.getInstance().getActionBuilder("net.sf.gridarta");
65 
69  @NotNull
70  private static final Preferences PREFERENCES = Preferences.userNodeForPackage(MainControl.class);
71 
76  @NotNull
77  private final BorderPanel borderPanel;
78 
82  @NotNull
83  private final Map<Component, Tab> openTabs = new IdentityHashMap<>();
84 
88  @NotNull
89  private final ButtonListsListener buttonListsListener = (prevTab, tab) -> {
90  if (prevTab != null) {
91  close(prevTab);
92  }
93  if (tab != null) {
94  open(tab);
95  }
96  };
97 
101  @NotNull
103 
108  public TabbedPanel(@NotNull final Component centerComponent) {
109  final BorderPanelListener borderPanelListener = new BorderPanelListener() {
110 
111  @Override
112  public void sizeChanged(@NotNull final Component component, final int size) {
113  final Tab tab = openTabs.get(component);
114  if (tab != null) {
115  tab.setSize(size);
116  }
117  }
118 
119  @Override
120  public void size2Changed(@NotNull final Location location, final int size2) {
121  PREFERENCES.putInt(TAB_PREFIX + location.getName() + ".position", size2);
122  }
123 
124  @Override
125  public int getSize2(final Location location) {
126  return PREFERENCES.getInt(TAB_PREFIX + location.getName() + ".position", -1);
127  }
128 
129  };
130  borderPanel = new BorderPanel(centerComponent, borderPanelListener);
131  setLayout(new BorderLayout());
132  add(borderPanel, BorderLayout.CENTER);
133  }
134 
139  public void addTab(@NotNull final Tab tab) {
140  final DoubleButtonList buttonList = buttonLists.addTab(tab);
141  fillContextMenu(tab, true);
142  tabAdded(tab, buttonList, tab.isOpen());
143  }
144 
153  @Nullable
154  public Tab getActiveTab(@NotNull final Location location, final boolean alternativeLocation) {
155  return buttonLists.getActiveTab(location, alternativeLocation);
156  }
157 
163  public void moveTab(@NotNull final Tab tab, @NotNull final Location location) {
164  if (tab.getLocation() == location) {
165  return;
166  }
167 
168  final boolean open = tab.isOpen();
169  final DoubleButtonList[] result = buttonLists.moveTab(tab, location);
170  final DoubleButtonList oldButtonList = result[0];
171  final DoubleButtonList newButtonList = result[1];
172 
173  fillContextMenu(tab, false);
174  tabRemoved(oldButtonList);
175  tabAdded(tab, newButtonList, open);
176  }
177 
183  public void setTabSplitMode(@NotNull final Tab tab, final boolean splitMode) {
184  if (tab.isAlternativeLocation() == splitMode) {
185  return;
186  }
187 
188  final boolean open = tab.isOpen();
189  final DoubleButtonList buttonList = buttonLists.toggleTabSplitMode(tab);
190  if (open) {
191  buttonList.selectButton(tab.getButton(), tab.isAlternativeLocation());
192  }
193  }
194 
202  private void tabAdded(@NotNull final Tab tab, @NotNull final DoubleButtonList buttonList, final boolean open) {
203  if (buttonList.getButtonCount() == 1) {
204  add(buttonList.getButtons(), tab.getLocation().getBorderLocation());
205  validate();
206  }
207 
208  if (open) {
209  buttonList.selectButton(tab.getButton(), tab.isAlternativeLocation());
210  }
211  }
212 
218  private void tabRemoved(@NotNull final DoubleButtonList buttonList) {
219  if (buttonList.getButtonCount() == 0) {
220  remove(buttonList.getButtons());
221  validate();
222  }
223  }
224 
230  private void fillContextMenu(@NotNull final Tab tab, final boolean initialize) {
231  final MoveToActions moveToActions = new MoveToActions(tab, this);
232  if (initialize) {
233  final JPopupMenu popupMenu = tab.getPopupMenu();
234  final ToggleAction splitModeAction = (ToggleAction) ACTION_BUILDER.createToggle(false, "tabSplitMode", moveToActions);
235  splitModeAction.setSelected(tab.isAlternativeLocation());
236  popupMenu.insert(splitModeAction.createCheckBoxMenuItem(), 0);
237  tab.setSplitModeAction(splitModeAction);
238  }
239 
240  final JMenu moveToMenu = tab.getMoveToMenu();
241  MenuUtils.removeAll(moveToMenu);
242  final Location location = tab.getLocation();
243  for (final Location thisLocation : Location.values()) {
244  if (thisLocation != location) {
245  moveToMenu.add(ACTION_BUILDER.createAction(true, "tabButtonMoveTo" + thisLocation.getName(), moveToActions));
246  }
247  }
248  }
249 
254  private void open(@NotNull final Tab tab) {
255  openTabs.put(tab.getComponent(), tab);
256  borderPanel.setComponent(tab.getLocation(), tab.getComponent(), tab.isAlternativeLocation(), tab.getSize());
257  tab.setOpen(true);
258  }
259 
264  private void close(@NotNull final Tab tab) {
265  closeInt(tab);
266  tab.setOpen(false);
267  }
268 
273  private void closeInt(final Tab tab) {
275  openTabs.remove(tab.getComponent());
276  }
277 
278 }
net.sf.gridarta.gui.utils.borderpanel.BorderPanel.setComponent
void setComponent(@NotNull final Location location, @NotNull final Component component, final boolean alternativeLocation, final int size)
Sets the optional Component for a location.
Definition: BorderPanel.java:86
net.sf.gridarta.gui.utils.tabbedpanel.Tab.isAlternativeLocation
boolean isAlternativeLocation()
Returns whether the button is shown in the alternative location.
Definition: Tab.java:339
net.sf.gridarta
Base package of all Gridarta classes.
net.sf.gridarta.gui.utils.tabbedpanel.DoubleButtonList
A list of buttons divided into two parts.
Definition: DoubleButtonList.java:36
net.sf.gridarta.gui.utils.tabbedpanel.ButtonListsListener
Interface for listeners interested in ButtonLists related events.
Definition: ButtonListsListener.java:28
net.sf.gridarta.gui.utils.borderpanel.BorderPanel.unsetComponent
void unsetComponent(@NotNull final Location location, final boolean alternativeLocation)
Unsets the optional Component for a location.
Definition: BorderPanel.java:96
net.sf.gridarta.gui.utils.MenuUtils.removeAll
static void removeAll(@NotNull final JMenu menu)
Remove all menu entries.
Definition: MenuUtils.java:72
net.sf.gridarta.gui.utils.tabbedpanel.ButtonLists.getActiveTab
Tab getActiveTab(@NotNull final Location location, final boolean alternativeLocation)
Returns the active Tab on a given Location of the main view.
Definition: ButtonLists.java:135
net.sf
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.open
void open(@NotNull final Tab tab)
Opens a Tab.
Definition: TabbedPanel.java:254
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.tabAdded
void tabAdded(@NotNull final Tab tab, @NotNull final DoubleButtonList buttonList, final boolean open)
Called whenever a Tab has been added to a ButtonList.
Definition: TabbedPanel.java:202
net.sf.gridarta.gui.utils.tabbedpanel.Tab.getComponent
Component getComponent()
Returns the Component that is shown when this tab is active.
Definition: Tab.java:295
net.sf.gridarta.gui.utils.tabbedpanel.Tab
A tab in a TabbedPanel component.
Definition: Tab.java:54
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.closeInt
void closeInt(final Tab tab)
Closes a Tab but does not update the tab's open status.
Definition: TabbedPanel.java:273
net.sf.gridarta.gui
Graphical User Interface of Gridarta.
net.sf.gridarta.gui.utils.tabbedpanel.ButtonLists.moveTab
DoubleButtonList[] moveTab(@NotNull final Tab tab, @NotNull final Location location)
Moves a Tab to a new location.
Definition: ButtonLists.java:93
net.sf.gridarta.gui.utils.tabbedpanel.Tab.setSize
void setSize(final int size)
Sets the tab's size.
Definition: Tab.java:393
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.borderPanel
final BorderPanel borderPanel
The BorderPanel.
Definition: TabbedPanel.java:77
net
net.sf.gridarta.gui.utils.tabbedpanel.DoubleButtonList.selectButton
void selectButton(@NotNull final AbstractButton button, final boolean alternativeLocation)
Selects a button.
Definition: DoubleButtonList.java:110
net.sf.gridarta.gui.utils.tabbedpanel.Tab.getLocation
Location getLocation()
Returns the tab's location.
Definition: Tab.java:361
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel
A Component that always displays another component and optionally a number of tabs around it.
Definition: TabbedPanel.java:47
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.TabbedPanel
TabbedPanel(@NotNull final Component centerComponent)
Creates a new instance.
Definition: TabbedPanel.java:108
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.serialVersionUID
static final long serialVersionUID
The serial version UID.
Definition: TabbedPanel.java:58
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.fillContextMenu
void fillContextMenu(@NotNull final Tab tab, final boolean initialize)
Fills in context popup menu entries for a tab in a given location.
Definition: TabbedPanel.java:230
net.sf.gridarta.gui.utils.borderpanel.BorderPanelListener
Interface for listeners interested in BorderPanel related events.
Definition: BorderPanelListener.java:29
net.sf.gridarta.gui.utils.tabbedpanel.ButtonLists.addTab
DoubleButtonList addTab(@NotNull final Tab tab)
Adds a Tab to the button list associated with the tab's location.
Definition: ButtonLists.java:76
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.openTabs
final Map< Component, Tab > openTabs
The Tabs currently shown in borderPanel.
Definition: TabbedPanel.java:83
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.getActiveTab
Tab getActiveTab(@NotNull final Location location, final boolean alternativeLocation)
Returns the active Tab on a given Location of the main view.
Definition: TabbedPanel.java:154
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.buttonLists
final ButtonLists buttonLists
The list of buttons for each Location.
Definition: TabbedPanel.java:102
net.sf.gridarta.gui.utils.borderpanel.Location.getName
abstract String getName()
Returns a name for building resource keys.
net.sf.gridarta.gui.utils.borderpanel.BorderPanel
A Component that permanently displays another Component and optionally displays more components on th...
Definition: BorderPanel.java:34
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.tabRemoved
void tabRemoved(@NotNull final DoubleButtonList buttonList)
Called whenever a Tab has been added from a ButtonList.
Definition: TabbedPanel.java:218
net.sf.gridarta.gui.utils.borderpanel.Location
A location.
Definition: Location.java:33
net.sf.gridarta.gui.utils.tabbedpanel.ButtonLists.toggleTabSplitMode
DoubleButtonList toggleTabSplitMode(@NotNull final Tab tab)
Definition: ButtonLists.java:112
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.TAB_PREFIX
static final String TAB_PREFIX
The key used to store the preferred height of a tab.
Definition: TabbedPanel.java:53
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.setTabSplitMode
void setTabSplitMode(@NotNull final Tab tab, final boolean splitMode)
Toggles split mode for the given tab.
Definition: TabbedPanel.java:183
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.ACTION_BUILDER
static final ActionBuilder ACTION_BUILDER
The ActionBuilder.
Definition: TabbedPanel.java:64
net.sf.gridarta.gui.utils.borderpanel
Definition: BorderPanel.java:20
net.sf.gridarta.gui.utils.tabbedpanel.ButtonLists
Maintains a set of ButtonLists for Locations of Tabs.
Definition: ButtonLists.java:34
net.sf.gridarta.gui.utils.tabbedpanel.MoveToActions
Defines ActionMethods to move tab locations.
Definition: MoveToActions.java:30
net.sf.gridarta.gui.utils
Definition: AnimationComponent.java:20
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.addTab
void addTab(@NotNull final Tab tab)
Adds a tab.
Definition: TabbedPanel.java:139
net.sf.gridarta.gui.utils.MenuUtils
Utility class implementing menu related functions.
Definition: MenuUtils.java:39
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.close
void close(@NotNull final Tab tab)
Closes a Tab.
Definition: TabbedPanel.java:264
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.buttonListsListener
final ButtonListsListener buttonListsListener
The ButtonListsListener attached to buttonLists.
Definition: TabbedPanel.java:89
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.PREFERENCES
static final Preferences PREFERENCES
The Preferences.
Definition: TabbedPanel.java:70
net.sf.gridarta.gui.utils.tabbedpanel.TabbedPanel.moveTab
void moveTab(@NotNull final Tab tab, @NotNull final Location location)
Moves the tab to the given location.
Definition: TabbedPanel.java:163
net.sf.gridarta.MainControl
Interface used as preferences location.
Definition: MainControl.java:27