001package org.vishia.gral.widget; 002 003import java.util.List; 004import java.util.Map; 005 006import org.vishia.gral.base.GralTable; 007import org.vishia.gral.base.GralWidget; 008import org.vishia.gral.ifc.GralMngBuild_ifc; 009import org.vishia.gral.ifc.GralMng_ifc; 010import org.vishia.gral.ifc.GralUserAction; 011import org.vishia.gral.ifc.GralTableLine_ifc; 012import org.vishia.util.Assert; 013import org.vishia.util.KeyCode; 014import org.vishia.util.Removeable; 015 016/**The base class for lists which supports nested selections. The associated widget is a table. 017 * The action listener {@link #actionTable} captures all key and mouse activities on the table-widget. 018 * It is the base class for file selection and command selection. 019 * The base idea is, left and right keys navigates in a tree to outer and deeper nodes. The table 020 * shows only members of the current node. A text line shows the current node path. 021 * It may be possible to switch to a tree presentation (TODO). But this complex widget should occupy 022 * only a simple rectangle of a GUI, not some windows etc. It may be less in spread too if necessary. 023 * <br><br> 024 * Note: this class should not be a derived class of {@link GralTable}, because instances of derived classes 025 * should be created as final compositions in the main thread before the table can be presented 026 * in the graphic thread. Therefore the aggregation {@link #wdgdTable} cannot be final. It is set 027 * only when {@link #setToPanel(GralMngBuild_ifc, String, int, int[], char)} is called. 028 * <pre> 029 * GralSelectList 030 * |--{@link #wdgdTable}--->GralTable TableLineData 031 * |---idxLine------*>| 032 * |---tableLines---*>| 033 * </pre> 034 * @author Hartmut Schorrig 035 * 036 */ 037public abstract class GralSelectList<UserData> implements Removeable //extends GralWidget 038{ 039 /**Version and history: 040 * <ul> 041 * <li>2018-10-28 Hartmut chg: {@link #createImplWidget_Gthread()} instead setToPanel(mng) 042 * <li>2011-11-18 chg: This class does not inherit from GralWidget now. The GralWidget, which represents this class, 043 * is referenced with the public aggregation {@link #wdgdTable}. Only this instance is registered on a panel 044 * calling {@link #setToPanel(GralMngBuild_ifc, String, int, int[], char)}. 045 * <li>2011-10-02 chg: Uses keycodes from {@link KeyCode} now, 046 * <li>2011-10-02 chg: {@link #actionOk(Object, GralTableLine_ifc)} returns boolean now, false if no action is done. 047 * <li>older- TODO 048 * </ul> 049 * <b>Copyright/Copyleft</b>: 050 * For this source the LGPL Lesser General Public License, 051 * published by the Free Software Foundation is valid. 052 * It means: 053 * <ol> 054 * <li> You can use this source without any restriction for any desired purpose. 055 * <li> You can redistribute copies of this source to everybody. 056 * <li> Every user of this source, also the user of redistribute copies 057 * with or without payment, must accept this license for further using. 058 * <li> But the LPGL ist not appropriate for a whole software product, 059 * if this source is only a part of them. It means, the user 060 * must publish this part of source, 061 * but don't need to publish the whole source of the own product. 062 * <li> You can study and modify (improve) this source 063 * for own using or for redistribution, but you have to license the 064 * modified sources likewise under this LGPL Lesser General Public License. 065 * You mustn't delete this Copyright/Copyleft inscription in this source file. 066 * </ol> 067 * If you are indent to use this sources without publishing its usage, you can get 068 * a second license subscribing a special contract with the author. 069 * 070 * @author Hartmut Schorrig = hartmut.schorrig@vishia.de 071 * 072 */ 073 public static final String version = "2018-10-28"; 074 075 076 /**The table which is showing in the widget. */ 077 public GralTable<UserData> wdgdTable; 078 079 080 /**The keys for left and right navigation. Default it is shift + left and right arrow key. 081 * 082 */ 083 protected int keyLeft = KeyCode.alt + KeyCode.left, keyRight = KeyCode.alt + KeyCode.right; 084 085 086 087 /**Not used yet, register actions? */ 088 protected Map<String, GralUserAction> actions; 089 090 protected GralSelectList(String posName, int rows, int[] columns, char size) //String name, GralWidgetMng mng) 091 { 092 if(posName == null){ 093 Assert.stop(); 094 } 095 wdgdTable = new GralTable<UserData>(posName, rows, columns); 096 wdgdTable.setVisible(true); 097 } 098 099 100 /**The left and right key codes for selection left and right can be changed. 101 * The key code is a number maybe in combination with alt, ctrl, shift see {@link KeyCode}. 102 * @param keyLeft Key code for outer selection 103 * @param keyRight KeyCode for deeper selection 104 */ 105 public final void setLeftRightKeys(int keyLeft, int keyRight){ 106 this.keyLeft = keyLeft; this.keyRight = keyRight; 107 } 108 109 //public SelectList() 110 //{ 111 // super('l'); 112 //} 113 114 115 /** 116 * @param panel 117 * @param identArgJbat 118 * @param rows 119 * @param columns 120 * @param size 121 */ 122 public void XXXsetToPanel(GralMngBuild_ifc gralMng) 123 { 124 wdgdTable.setToPanel(gralMng); 125 //wdgdTable = gralMng.addTable(name, rows, columns); 126 wdgdTable.setActionChange(actionTable); 127 } 128 129 130 131 /** 132 */ 133 public void createImplWidget_Gthread() 134 { 135 wdgdTable.createImplWidget_Gthread(); 136 wdgdTable.setActionChange(actionTable); 137 } 138 139 140 141 public void set(List<String[]> listData) 142 { 143 for(String[] data: listData){ 144 wdgdTable.setValue(GralMng_ifc.cmdInsert, 0, data[0]); 145 } 146 } 147 148 149 /**Sets the focus of the associated table widget. 150 * @return true if focused. 151 */ 152 public boolean setFocus(){ wdgdTable.setFocus(); return true; } 153 154 /**Removes all data and all widgets of this class. */ 155 @Override public boolean remove(){ 156 wdgdTable.remove(); 157 return true; 158 } 159 160 /**Action if a table line is selected and entered. Its either a double click with the mouse 161 * or click of OK (Enter) button. 162 * @param userData The user data stored in the line of table. 163 */ 164 protected abstract boolean actionOk(Object userData, GralTableLine_ifc<UserData> line); 165 166 /**Action if a table line is selected and ctrl-left is pressed or the release button is pressed. 167 * @param userData The user data stored in the line of table. 168 */ 169 protected abstract void actionLeft(Object userData, GralTableLine_ifc<UserData> line); 170 171 /**Action if a table line is selected and ctrl-right is pressed or the release button is pressed. 172 * @param userData The user data stored in the line of table. 173 */ 174 protected abstract void actionRight(Object userData, GralTableLine_ifc<UserData> line); 175 176 177 /**Action if a table line is selected and any other key is pressed or the context menu is invoked. 178 * @param key code or mouse code, one of constans from {@link KeyCode}. 179 * @param userData The user data stored in the line of table. 180 * @param line The table line. 181 * @return true if is was relevant for the key. 182 */ 183 protected abstract boolean actionUserKey(int key, Object userData, GralTableLine_ifc<UserData> line); 184 185 186 private final GralUserAction actionTable = new GralUserAction("actionTable") 187 { 188 189 @Override public boolean userActionGui(int keyCode, GralWidget widgdTable, Object... params) 190 { 191 //assert(sIntension.equals("table-key")); 192 @SuppressWarnings("unchecked") 193 GralTableLine_ifc<UserData> line = (GralTableLine_ifc<UserData>)params[0]; 194 Object data = line == null ? null : line.getUserData(); 195 //int keyCode = (Integer)params[1]; 196 boolean done = true; 197 if(data !=null) { 198 if(keyCode == keyLeft){ actionLeft(data, line); } 199 else if(keyCode == keyRight){ actionRight(data, line); } 200 else if(keyCode == KeyCode.enter){ done = actionOk(data, line); } 201 else if(keyCode == KeyCode.mouse1Double){ done = actionOk(data, line); } 202 else { done = actionUserKey(keyCode, data, line); } 203 } else { 204 done = false; 205 } 206 return done; 207 } 208 209 210 }; 211 212 213 214 void stop(){} 215 216}