/*******************************************************************************
* Copyright (c) 2016 Weasis Team and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nicolas Roduit - initial API and implementation
*******************************************************************************/
package org.weasis.core.api.gui.util;
import java.util.Arrays;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JMenu;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import org.weasis.core.api.service.AuditLog;
public abstract class ComboItemListener<T> extends BasicActionState implements ListDataListener, ChangeListener {
protected final DefaultComboBoxModel<T> model;
public ComboItemListener(ActionW action, T[] objects) {
super(action);
model = (objects != null) ? new DefaultComboBoxModel<>(objects) : new DefaultComboBoxModel<>();
model.addListDataListener(this);
}
@Override
public void contentsChanged(ListDataEvent e) {
Object val = model.getSelectedItem();
itemStateChanged(val);
AuditLog.LOGGER.info("action:{} val:{}", action.cmd(), val); //$NON-NLS-1$
}
@Override
public void intervalAdded(ListDataEvent e) {
// Do nothing
}
@Override
public void intervalRemoved(ListDataEvent e) {
// Do nothing
}
@Override
public void stateChanged(ChangeEvent evt) {
// Do nothing
}
@Override
public String toString() {
return action.getTitle();
}
@Override
public ActionW getActionW() {
return action;
}
public abstract void itemStateChanged(Object object);
@Override
public boolean registerActionState(Object c) {
if (super.registerActionState(c)) {
if (c instanceof ComboBoxModelAdapter) {
((ComboBoxModelAdapter<T>) c).setModel(model);
}
return true;
}
return false;
}
@Override
public void unregisterActionState(Object c) {
super.unregisterActionState(c);
if (c instanceof ComboBoxModelAdapter) {
((ComboBoxModelAdapter<T>) c).setModel(new DefaultComboBoxModel<T>());
}
}
public synchronized Object[] getAllItem() {
Object[] array = new Object[model.getSize()];
for (int i = 0; i < array.length; i++) {
array[i] = model.getElementAt(i);
}
return array;
}
public synchronized Object getFirstItem() {
return model.getElementAt(0);
}
public synchronized Object getSelectedItem() {
return model.getSelectedItem();
}
public synchronized void setSelectedItem(Object object) {
model.setSelectedItem(object);
}
public synchronized void setSelectedItemWithoutTriggerAction(Object object) {
model.removeListDataListener(this);
model.setSelectedItem(object);
model.addListDataListener(this);
}
public synchronized void setDataListWithoutTriggerAction(T[] objects) {
setDataList(objects, false);
}
public synchronized void setDataList(T[] objects) {
setDataList(objects, true);
}
private boolean isDataEquals(Object[] objects) {
if (model.getSize() != objects.length) {
return false;
}
Object[] data = new Object[objects.length];
for (int i = 0; i < data.length; i++) {
data[i] = model.getElementAt(i);
}
return Arrays.equals(data, objects);
}
protected synchronized void setDataList(T[] objects, boolean doTriggerAction) {
if (isDataEquals(objects)) {
// Do not update model and menu model,
return;
}
Object oldSelection = model.getSelectedItem();
model.removeListDataListener(this);
model.removeAllElements();
if (objects != null && objects.length > 0) {
boolean oldSelectionStillExist = false;
for (T object : objects) {
model.addElement(object);
if (object.equals(oldSelection)) {
oldSelectionStillExist = true;
}
}
for (Object c : components) {
if (c instanceof ComboBoxModelAdapter) {
((ComboBoxModelAdapter<T>) c).setModel(model);
}
}
model.setSelectedItem(null);
if (doTriggerAction) {
model.addListDataListener(this);
}
if (oldSelection != null && oldSelectionStillExist) {
model.setSelectedItem(oldSelection);
} else {
model.setSelectedItem(objects[0]);
}
if (!doTriggerAction) {
model.addListDataListener(this);
}
}
}
public DefaultComboBoxModel<T> getModel() {
return model;
}
public JToogleButtonGroup<T> createButtonGroup() {
final JToogleButtonGroup<T> group = new JToogleButtonGroup<>();
registerActionState(group);
return group;
}
public JComboBox<T> createCombo(int width) {
final ComboItems combo = new ComboItems();
registerActionState(combo);
JMVUtils.setPreferredWidth(combo, width, width);
// Update UI before adding the Tooltip feature in the combobox list
combo.updateUI();
JMVUtils.addTooltipToComboList(combo);
return combo;
}
public JMenu createUnregisteredRadioMenu(String title) {
GroupRadioMenu<T> radioMenu = new GroupRadioMenu<>();
radioMenu.setModel(model);
JMenu menu = radioMenu.createMenu(title);
if (!enabled) {
menu.setEnabled(false);
}
return menu;
}
public GroupPopup createGroupRadioMenu() {
GroupRadioMenu<T> radioMenu = new GroupRadioMenu<>();
radioMenu.setModel(model);
registerActionState(radioMenu);
return radioMenu;
}
public GroupPopup createUnregisteredGroupRadioMenu() {
GroupRadioMenu<T> radioMenu = new GroupRadioMenu<>();
radioMenu.setModel(model);
return radioMenu;
}
// Trick to wrap JComboBox in the same interface as the GroupRadioMenu
@SuppressWarnings("serial")
class ComboItems extends JComboBox<T> implements ComboBoxModelAdapter<T> {
}
}