Crossfire JXClient, Trunk
GUIComboBox.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff
19  * Copyright (C) 2006-2017,2019-2023 Andreas Kirschbaum
20  * Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger
21  */
22 
23 package com.realtime.crossfire.jxclient.gui.combobox;
24 
34 import java.awt.Component;
35 import java.awt.Dimension;
36 import java.awt.event.ActionListener;
37 import java.util.List;
38 import java.util.regex.Pattern;
39 import javax.swing.DefaultComboBoxModel;
40 import javax.swing.JComboBox;
41 import javax.swing.JList;
42 import org.jetbrains.annotations.NotNull;
43 import org.jetbrains.annotations.Nullable;
44 
50 public abstract class GUIComboBox<T> extends AbstractGUIElement {
51 
55  private static final long serialVersionUID = 1;
56 
60  @NotNull
61  private static final Pattern PATTERN_BOLD_BEGIN = Pattern.compile("\\[b]");
62 
66  @NotNull
67  private static final Pattern PATTERN_BOLD_END = Pattern.compile("\\[/b]");
68 
72  @NotNull
73  private final DefaultComboBoxModel<T> model = new DefaultComboBoxModel<>();
74 
78  @Nullable
79  private final GUILabelLog label;
80 
84  @NotNull
85  private final JComboBox<T> comboBox = new JComboBox<>(model);
86 
90  @NotNull
91  private final ActionListener actionListener = e -> updateSelectedItem();
92 
96  private boolean inhibitActionListener;
97 
106  protected GUIComboBox(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @Nullable final GUILabelLog label, @NotNull final GuiFactory guiFactory) {
108  this.label = label;
109  comboBox.setFocusable(false);
110  comboBox.setRenderer(this::getListCellRendererComponent);
111  comboBox.setMaximumRowCount(18);
112  comboBox.addActionListener(actionListener);
113  add(comboBox);
114  }
115 
116  @Override
117  public void dispose() {
118  super.dispose();
119  comboBox.removeActionListener(actionListener);
120  }
121 
122  @Override
123  public Dimension getPreferredSize() {
124  final Dimension result = comboBox.getPreferredSize();
125  return result == null ? super.getPreferredSize() : result;
126  }
127 
128  @Override
129  public Dimension getMinimumSize() {
130  final Dimension result = comboBox.getMinimumSize();
131  return result == null ? super.getMinimumSize() : result;
132  }
133 
134  @Override
135  public void setBounds(final int x, final int y, final int width, final int height) {
136  super.setBounds(x, y, width, height);
137  comboBox.setSize(width, height);
138  }
139 
144  protected void updateModel(@Nullable final List<T> elements) {
145  final boolean updateModel;
146  if (elements == null) {
147  updateModel = model.getSize() != 0;
148  } else {
149  final int size = model.getSize();
150  if (size == elements.size()) {
151  int i;
152  for (i = 0; i < size; i++) {
153  if (!model.getElementAt(i).equals(elements.get(i))) {
154  break;
155  }
156  }
157  updateModel = i < size;
158  } else {
159  updateModel = true;
160  }
161  }
162 
163  setVisible(elements != null);
164  if (updateModel) {
165  try {
166  inhibitActionListener = true;
167  model.removeAllElements();
168  if (elements != null) {
169  for (T element : elements) {
170  model.addElement(element);
171  }
172  }
173  } finally {
174  inhibitActionListener = false;
175  }
177  }
178  }
179 
189  @NotNull
190  protected abstract Component getListCellRendererComponent(@NotNull final JList<? extends T> list, @Nullable final T value, final int index, final boolean selected, final boolean cellHasFocus);
191 
195  protected void updateSelectedItem() {
196  if (inhibitActionListener) {
197  return;
198  }
199 
200  @SuppressWarnings("unchecked") final T item = (T)comboBox.getSelectedItem();
201  final String text = item == null ? "" : getDescription(item);
202 
203  if (label != null) {
204  setChanged();
206  }
207  updateSelectedItem(item);
208  tooltipChanged();
209  }
210 
215  protected abstract void updateSelectedItem(@Nullable final T item);
216 
221  protected void setSelectedItem(@NotNull final T item) {
222  comboBox.setSelectedItem(item);
223  }
224 
230  @NotNull
231  protected abstract String getDescription(@Nullable T item);
232 
233  @Nullable
234  @Override
236  @SuppressWarnings("unchecked") final T item = (T)comboBox.getSelectedItem();
237  final String text = item == null ? "" : getDescription(item);
238  if (text.isEmpty()) {
239  return null;
240  }
241 
242  final StringBuilder sb = new StringBuilder();
243  for (final String line0 : text.split("\n")) {
244  final String line = line0.trim();
245 
246  int index = 0;
247  while (line.length() > index+80) {
248  int nextIndex = line.lastIndexOf(' ', index+80);
249  if (nextIndex == -1) {
250  nextIndex = line.indexOf(' ', index+80);
251  if (nextIndex == -1) {
252  nextIndex = line.length();
253  }
254  if (nextIndex > index+140) {
255  nextIndex = index+140;
256  }
257  }
258  sb.append(sb.length() == 0 ? "<html>" : "<br>").append(line, index, nextIndex);
259 
260  index = nextIndex;
261  while (index < line.length() && line.charAt(index) == ' ') {
262  index++;
263  }
264  }
265  sb.append(sb.length() == 0 ? "<html>" : "<br>").append(line, index, line.length());
266  }
267  return newTooltipText(PATTERN_BOLD_END.matcher(PATTERN_BOLD_BEGIN.matcher(sb.toString()).replaceAll("<b>")).replaceAll("</b>"));
268  }
269 
270 }
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.newTooltipText
TooltipText newTooltipText(@Nullable final String tooltipText)
Definition: AbstractGUIElement.java:247
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.name
final String name
Definition: AbstractGUIElement.java:77
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.skin.skin
Definition: DefaultJXCSkin.java:23
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.PATTERN_BOLD_BEGIN
static final Pattern PATTERN_BOLD_BEGIN
Definition: GUIComboBox.java:61
com.realtime.crossfire.jxclient.gui.log.GUILabelLog.updateText
void updateText(@NotNull final CharSequence string, final int type, final int subtype)
Definition: GUILabelLog.java:82
com.realtime.crossfire.jxclient.skin
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.getDescription
abstract String getDescription(@Nullable T item)
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.setSelectedItem
void setSelectedItem(@NotNull final T item)
Definition: GUIComboBox.java:221
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.actionListener
final ActionListener actionListener
Definition: GUIComboBox.java:91
com.realtime.crossfire.jxclient.skin.skin.GuiFactory
Definition: GuiFactory.java:41
com.realtime.crossfire.jxclient.gui.log.GUILabelLog
Definition: GUILabelLog.java:38
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.getListCellRendererComponent
abstract Component getListCellRendererComponent(@NotNull final JList<? extends T > list, @Nullable final T value, final int index, final boolean selected, final boolean cellHasFocus)
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.tooltipChanged
void tooltipChanged()
Definition: AbstractGUIElement.java:265
com.realtime.crossfire.jxclient.gui.log
Definition: Buffer.java:23
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox
Definition: GUIComboBox.java:50
com.realtime.crossfire.jxclient.protocol
Definition: MagicMap.java:23
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.GUIComboBox
GUIComboBox(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @Nullable final GUILabelLog label, @NotNull final GuiFactory guiFactory)
Definition: GUIComboBox.java:106
com.realtime.crossfire.jxclient.protocol.MessageType
Definition: MessageType.java:33
com.realtime.crossfire.jxclient.protocol.MessageType.MSG_TYPE_JXCLIENT
static final int MSG_TYPE_JXCLIENT
Definition: MessageType.java:136
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.serialVersionUID
static final long serialVersionUID
Definition: GUIComboBox.java:55
com.realtime.crossfire.jxclient.gui.log.GUILog
Definition: GUILog.java:55
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.model
final DefaultComboBoxModel< T > model
Definition: GUIComboBox.java:73
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.updateSelectedItem
void updateSelectedItem()
Definition: GUIComboBox.java:195
com.realtime.crossfire.jxclient.protocol.MessageType.MSG_SUBTYPE_JXCLIENT_COMBOBOX
static final int MSG_SUBTYPE_JXCLIENT_COMBOBOX
Definition: MessageType.java:484
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.label
final GUILabelLog label
Definition: GUIComboBox.java:79
com.realtime.crossfire.jxclient.gui
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.setBounds
void setBounds(final int x, final int y, final int width, final int height)
Definition: GUIComboBox.java:135
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.inhibitActionListener
boolean inhibitActionListener
Definition: GUIComboBox.java:96
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.dispose
void dispose()
Definition: GUIComboBox.java:117
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.elementListener
final GUIElementListener elementListener
Definition: AbstractGUIElement.java:89
com.realtime.crossfire.jxclient.gui.gui.TooltipManager
Definition: TooltipManager.java:33
com.realtime.crossfire.jxclient.gui.gui.GUIElement
Definition: GUIElement.java:33
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.updateModel
void updateModel(@Nullable final List< T > elements)
Definition: GUIComboBox.java:144
com.realtime.crossfire.jxclient.gui.gui
Definition: AbstractGUIElement.java:23
com.realtime.crossfire.jxclient.gui.gui.TooltipText
Definition: TooltipText.java:31
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.comboBox
final JComboBox< T > comboBox
Definition: GUIComboBox.java:85
com.realtime.crossfire
com.realtime
com
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.getPreferredSize
Dimension getPreferredSize()
Definition: GUIComboBox.java:123
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.setChanged
void setChanged()
Definition: AbstractGUIElement.java:223
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement
Definition: AbstractGUIElement.java:37
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.guiFactory
final GuiFactory guiFactory
Definition: AbstractGUIElement.java:48
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.getTooltip
TooltipText getTooltip()
Definition: GUIComboBox.java:235
com.realtime.crossfire.jxclient.gui.gui.GUIElementListener
Definition: GUIElementListener.java:32
com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement.tooltipManager
final TooltipManager tooltipManager
Definition: AbstractGUIElement.java:83
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.PATTERN_BOLD_END
static final Pattern PATTERN_BOLD_END
Definition: GUIComboBox.java:67
com.realtime.crossfire.jxclient.gui.combobox.GUIComboBox.getMinimumSize
Dimension getMinimumSize()
Definition: GUIComboBox.java:129