1 package com.badlogic.gdx.tools.flame; 2 3 import java.awt.Dimension; 4 import java.awt.GridBagConstraints; 5 import java.awt.Insets; 6 7 import javax.swing.JScrollPane; 8 import javax.swing.JTable; 9 import javax.swing.ListSelectionModel; 10 import javax.swing.event.TableModelEvent; 11 import javax.swing.event.TableModelListener; 12 import javax.swing.table.DefaultTableModel; 13 14 import com.badlogic.gdx.utils.Array; 15 16 /** @author Inferno */ 17 public class TemplatePickerPanel<T> extends EditorPanel<Array<T>> implements LoaderButton.Listener<T> { 18 19 public interface Listener<T> { 20 void onTemplateChecked(T template, boolean isChecked); 21 } 22 23 Array<T> loadedTemplates; 24 Array<T> excludedTemplates; 25 Class<T> type; 26 JTable templatesTable; 27 DefaultTableModel templatesTableModel; 28 boolean isOneModelSelectedRequired = true, 29 isMultipleSelectionAllowed = true; 30 Listener listener; 31 int lastSelected = -1; 32 33 public TemplatePickerPanel (FlameMain editor, Array<T> value, Listener listener, Class<T> type){ 34 this(editor, value, listener, type, null, true, true); 35 } 36 37 public TemplatePickerPanel (FlameMain editor, Array<T> value, Listener listener, Class<T> type, LoaderButton<T> loaderButton){ 38 this(editor, value, listener, type, loaderButton, true, true); 39 } 40 41 public TemplatePickerPanel (FlameMain editor, Array<T> value, Listener listener, Class<T> type, 42 LoaderButton<T> loaderButton, boolean isOneModelSelectedRequired, boolean isMultipleSelectionAllowed) { 43 super(editor, "", ""); 44 this.type = type; 45 this.listener = listener; 46 this.isOneModelSelectedRequired = isOneModelSelectedRequired; 47 this.isMultipleSelectionAllowed = isMultipleSelectionAllowed; 48 loadedTemplates = new Array<T>(); 49 excludedTemplates = new Array<T>(); 50 initializeComponents(type, loaderButton); 51 setValue(value); 52 } 53 54 @Override 55 public void setValue (Array<T> value) { 56 super.setValue(value); 57 if(value == null) return; 58 if(!isMultipleSelectionAllowed && value.size >1) 59 throw new RuntimeException("Multiple selection must be enabled to ensure consistency between picked and available models."); 60 for(int i=0; i < value.size;++i ){ 61 T model = value.get(i); 62 int index = loadedTemplates.indexOf(model, true); 63 if(index >-1){ 64 EditorPanel.setValue(templatesTableModel, true, index, 1); 65 lastSelected = index; 66 } 67 } 68 } 69 70 public void setOneModelSelectionRequired(boolean isOneModelSelectionRequired){ 71 this.isOneModelSelectedRequired = isOneModelSelectionRequired; 72 } 73 74 public void setMultipleSelectionAllowed(boolean isMultipleSelectionAllowed){ 75 this.isMultipleSelectionAllowed = isMultipleSelectionAllowed; 76 } 77 78 public void setExcludedTemplates(Array<T> excludedTemplates){ 79 this.excludedTemplates.clear(); 80 this.excludedTemplates.addAll(excludedTemplates); 81 } 82 83 public void setLoadedTemplates(Array<T> templates){ 84 loadedTemplates.clear(); 85 loadedTemplates.addAll(templates); 86 loadedTemplates.removeAll(excludedTemplates, true); 87 templatesTableModel.getDataVector().removeAllElements(); 88 int i=0; 89 for(T template : templates){ 90 templatesTableModel.addRow(new Object[] {getTemplateName(template, i), false}); 91 i++; 92 } 93 lastSelected = -1; 94 setValue(value); 95 } 96 97 protected String getTemplateName(T template, int index){ 98 String name = editor.assetManager.getAssetFileName(template); 99 return name == null ? "template "+index:name; 100 } 101 102 103 public void reloadTemplates () { 104 setLoadedTemplates(editor.assetManager.getAll(type, new Array<T>())); 105 } 106 107 protected void initializeComponents (Class<T> type, LoaderButton<T> loaderButton) { 108 int i=0; 109 if(loaderButton != null){ 110 loaderButton.setListener(this); 111 contentPanel.add(loaderButton, new GridBagConstraints(0, i++, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 112 0, 0, 6), 0, 0)); 113 } 114 115 JScrollPane scroll = new JScrollPane(); 116 contentPanel.add(scroll, new GridBagConstraints(0, i, 1, 1, 1, 0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 117 0, 0, 6), 0, 0)); 118 { 119 templatesTable = new JTable() { 120 public Class getColumnClass (int column) { 121 return column == 1 ? Boolean.class : super.getColumnClass(column); 122 } 123 @Override 124 public Dimension getPreferredScrollableViewportSize () { 125 Dimension dim = super.getPreferredScrollableViewportSize(); 126 dim.height = getPreferredSize().height; 127 return dim; 128 } 129 }; 130 templatesTable.getTableHeader().setReorderingAllowed(false); 131 templatesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 132 scroll.setViewportView(templatesTable); 133 templatesTableModel = new DefaultTableModel(new String[0][0], new String[] {"Template", "Selected"}); 134 templatesTable.setModel(templatesTableModel); 135 reloadTemplates(); 136 137 templatesTableModel.addTableModelListener(new TableModelListener() { 138 public void tableChanged (TableModelEvent event) { 139 if (event.getColumn() != 1) return; 140 int row = event.getFirstRow(); 141 boolean checked = (Boolean)templatesTable.getValueAt(row, 1); 142 if( isOneModelSelectedRequired && (value.size == 1 && !checked) ){ 143 EditorPanel.setValue(templatesTableModel, true, row, 1); 144 return; 145 } 146 147 templateChecked(row, checked); 148 } 149 }); 150 } 151 } 152 153 protected void templateChecked (int index, Boolean isChecked) { 154 T template = loadedTemplates.get(index); 155 if(isChecked){ 156 if(!isMultipleSelectionAllowed){ 157 if(lastSelected >-1){ 158 value.removeValue(loadedTemplates.get(lastSelected), true); 159 EditorPanel.setValue(templatesTableModel, false, lastSelected, 1); 160 } 161 } 162 value.add(template); 163 lastSelected = index; 164 } 165 else { 166 value.removeValue(template, true); 167 } 168 listener.onTemplateChecked(template, isChecked); 169 } 170 171 @Override 172 public void onResourceLoaded (T model) { 173 reloadTemplates(); 174 if(lastSelected == -1 && isOneModelSelectedRequired){ 175 templateChecked(loadedTemplates.size-1, true); 176 } 177 else { 178 setValue(value); 179 } 180 181 revalidate(); 182 repaint(); 183 } 184 185 } 186