| 1 | //  Copyright 2004-2007 Jean-Francois Poilpret | 
| 2 | // | 
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
| 4 | // you may not use this file except in compliance with the License. | 
| 5 | // You may obtain a copy of the License at | 
| 6 | // | 
| 7 | //     http://www.apache.org/licenses/LICENSE-2.0 | 
| 8 | // | 
| 9 | // Unless required by applicable law or agreed to in writing, software | 
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | 
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
| 12 | // See the License for the specific language governing permissions and | 
| 13 | // limitations under the License. | 
| 14 |   | 
| 15 | package net.sourceforge.hiveboard.dialog; | 
| 16 |   | 
| 17 | import java.text.DecimalFormat; | 
| 18 | import java.util.HashSet; | 
| 19 | import java.util.Map; | 
| 20 | import java.util.Set; | 
| 21 |   | 
| 22 | import javax.swing.DefaultComboBoxModel; | 
| 23 | import javax.swing.JComboBox; | 
| 24 | import javax.swing.JComponent; | 
| 25 | import javax.swing.JFormattedTextField; | 
| 26 | import javax.swing.JLabel; | 
| 27 | import javax.swing.JScrollPane; | 
| 28 | import javax.swing.JTextField; | 
| 29 |   | 
| 30 | import org.jdesktop.application.Action; | 
| 31 | import org.jdesktop.application.Task; | 
| 32 |   | 
| 33 | import net.sourceforge.hiveboard.Account; | 
| 34 | import net.sourceforge.hiveboard.Board; | 
| 35 | import net.sourceforge.hiveboard.BoardTokenSetter; | 
| 36 | import net.sourceforge.hiveboard.WhiteBoardUserService; | 
| 37 | import net.sourceforge.hiveboard.command.AbstractTask; | 
| 38 | import net.sourceforge.hiveboard.main.ServerSettingsKeys; | 
| 39 | import net.sourceforge.hivegui.application.HiveGuiApplicationMain; | 
| 40 | import net.sourceforge.hivegui.component.TextListener; | 
| 41 | import net.sourceforge.hivegui.dialog.GenericDialog; | 
| 42 | import net.sourceforge.hivegui.table.BeanTable; | 
| 43 | import net.sourceforge.hivegui.table.DataListModel; | 
| 44 | import net.sourceforge.hivetranse.exception.DuplicateKeyException; | 
| 45 |   | 
| 46 | import zappini.designgridlayout.DesignGridLayout; | 
| 47 | import zappini.designgridlayout.Row; | 
| 48 |   | 
| 49 | // CSOFF: ClassDataAbstractionCouplingCheck | 
| 50 | public class BoardPanel extends AbstractBoardPanel | 
| 51 | { | 
| 52 |         static private final String        NAME_CREATE = "board-creation"; | 
| 53 |         static private final String        NAME_MODIFY = "board-modification"; | 
| 54 |          | 
| 55 |         public BoardPanel(        BeanTable<Account>                        tblAccounts,  | 
| 56 |                                   BoardTokenSetterRenderer        renderer, | 
| 57 |                                   WhiteBoardUserService                service, | 
| 58 |                                                 Map<String, Object>                        serverSettings) | 
| 59 |         { | 
| 60 |                 this(tblAccounts, renderer, service, serverSettings, null, true); | 
| 61 |         } | 
| 62 |          | 
| 63 |         public BoardPanel(        BeanTable<Account>                        tblAccounts,  | 
| 64 |                                   BoardTokenSetterRenderer        renderer, | 
| 65 |                                                 WhiteBoardUserService                service,  | 
| 66 |                                                 Map<String, Object>                        serverSettings, | 
| 67 |                                                 Board                                                board) | 
| 68 |         { | 
| 69 |                 this(tblAccounts, renderer, service, serverSettings, board.copy(), false); | 
| 70 |         } | 
| 71 |          | 
| 72 |         private BoardPanel(        BeanTable<Account>                        tblAccounts,  | 
| 73 |                                   BoardTokenSetterRenderer        renderer, | 
| 74 |                                                 WhiteBoardUserService                service,  | 
| 75 |                                                 Map<String, Object>                        serverSettings, | 
| 76 |                                                 Board                                                board, | 
| 77 |                                                 boolean                                                create) | 
| 78 |         { | 
| 79 |                 super(create ? NAME_CREATE : NAME_MODIFY); | 
| 80 |                 _service = service; | 
| 81 |                 _create = create; | 
| 82 |   | 
| 83 |                 _tblAccounts = tblAccounts; | 
| 84 |                 Integer maxBoardSize = (Integer) serverSettings.get(ServerSettingsKeys.MAX_BOARD_SIZE); | 
| 85 |                 _maxBoardSize = maxBoardSize.intValue(); | 
| 86 |                 _board = board; | 
| 87 |                 _accounts = _tblAccounts.getDataListModel(); | 
| 88 |   | 
| 89 |                 initComponentNames(); | 
| 90 |                 initComponents(renderer); | 
| 91 |                  | 
| 92 |                 _lblName.setLabelFor(_txfName); | 
| 93 |                 _lblDescription.setLabelFor(_txfDescription); | 
| 94 |                 _lblWidth.setLabelFor(_txfWidth); | 
| 95 |                 _lblHeight.setLabelFor(_txfHeight); | 
| 96 |                 _lblTokenSetter.setLabelFor(_cboTokenSetter); | 
| 97 |                 _lblParticipants.setLabelFor(_tblAccounts); | 
| 98 |                  | 
| 99 |                 DesignGridLayout layout = new DesignGridLayout(this);  | 
| 100 |                 setLayout(layout); | 
| 101 |                  | 
| 102 |                 // Add widgets to the panel | 
| 103 |                 layout.row().label(_lblName).add(_txfName); | 
| 104 |                 layout.row().label(_lblDescription).add(_txfDescription); | 
| 105 |                 layout.row().label(_lblWidth).add(_txfWidth).add(Row.EMPTY); | 
| 106 |                 layout.row().label(_lblHeight).add(_txfHeight).add(Row.EMPTY); | 
| 107 |                 layout.row().label(_lblTokenSetter).add(_cboTokenSetter); | 
| 108 |                 layout.row().label(_lblParticipants).add(new JScrollPane(_tblAccounts)); | 
| 109 |         } | 
| 110 |          | 
| 111 |         private void initComponents(BoardTokenSetterRenderer renderer) | 
| 112 |         { | 
| 113 |                 _cboTokenSetter.setModel( | 
| 114 |                         new DefaultComboBoxModel(BoardTokenSetter.class.getEnumConstants())); | 
| 115 |                 _cboTokenSetter.setRenderer(renderer); | 
| 116 |                                       | 
| 117 |                 TextListener listener = new TextListener() | 
| 118 |                 { | 
| 119 |                         @Override protected void contentUpdated() | 
| 120 |                         { | 
| 121 |                                 Number width = (Number) _txfWidth.getValue(); | 
| 122 |                                 Number height = (Number) _txfHeight.getValue(); | 
| 123 |                                 setAcceptEnabled(        _txfName.getText() != null | 
| 124 |                                                                 &&        _txfName.getText().length() != 0 | 
| 125 |                                                                 &&        width != null | 
| 126 |                                                                 &&        width.shortValue() > 0 | 
| 127 |                                                                 &&        height != null | 
| 128 |                                                                 &&        height.shortValue() > 0); | 
| 129 |                         } | 
| 130 |                 }; | 
| 131 |                  | 
| 132 |                 _txfName.getDocument().addDocumentListener(listener); | 
| 133 |                 _txfWidth.getDocument().addDocumentListener(listener); | 
| 134 |                 _txfHeight.getDocument().addDocumentListener(listener); | 
| 135 |                 if (!_create) | 
| 136 |                 { | 
| 137 |                         _txfWidth.setEnabled(false); | 
| 138 |                         _txfHeight.setEnabled(false); | 
| 139 |                 } | 
| 140 |         } | 
| 141 |          | 
| 142 |         private void initComponentNames() | 
| 143 |         { | 
| 144 |                 String name = getName(); | 
| 145 |                 _lblName.setName(name + "-name-label"); | 
| 146 |                 _txfName.setName(name + "-name"); | 
| 147 |                 _lblDescription.setName(name + "-description-label"); | 
| 148 |                 _txfDescription.setName(name + "-description"); | 
| 149 |                 _lblWidth.setName(name + "-width-label"); | 
| 150 |                 _txfWidth.setName(name + "-width"); | 
| 151 |                 _lblHeight.setName(name + "-height-label"); | 
| 152 |                 _txfHeight.setName(name + "-height"); | 
| 153 |                 _lblTokenSetter.setName(name + "-token-setter-label"); | 
| 154 |                 _cboTokenSetter.setName(name + "-token-setter"); | 
| 155 |                 _lblParticipants.setName(name + "-participants-list-label"); | 
| 156 |                 _tblAccounts.setName(name + "-participants-list"); | 
| 157 |         } | 
| 158 |   | 
| 159 |         @Override public void        reset() | 
| 160 |         { | 
| 161 |                 if (_create) | 
| 162 |                 { | 
| 163 |                         // If dialog for board creation, reinitialize a new Board | 
| 164 |                         _board = new Board(); | 
| 165 |                         setAcceptEnabled(false); | 
| 166 |                 } | 
| 167 |                 refresh(); | 
| 168 |         } | 
| 169 |          | 
| 170 |         @Action(enabledProperty = "acceptEnabled", block = Task.BlockingScope.WINDOW) | 
| 171 |         public Task        accept() | 
| 172 |         { | 
| 173 |                 if (!checkInput()) | 
| 174 |                 { | 
| 175 |                         return null; | 
| 176 |                 } | 
| 177 |   | 
| 178 |                 updateBoard(); | 
| 179 |   | 
| 180 |                 return new ModifyBoardTask(_application, _parent); | 
| 181 |         } | 
| 182 |   | 
| 183 |         private boolean        checkInput() | 
| 184 |         { | 
| 185 |                 JComponent badInputField = null; | 
| 186 |                 short width = ((Number) _txfWidth.getValue()).shortValue(); | 
| 187 |                 short height = ((Number) _txfHeight.getValue()).shortValue(); | 
| 188 |                 if (width > _maxBoardSize) | 
| 189 |                 { | 
| 190 |                         badInputField = _txfWidth; | 
| 191 |                 } | 
| 192 |                 else if (height > _maxBoardSize) | 
| 193 |                 { | 
| 194 |                         badInputField = _txfHeight; | 
| 195 |                 } | 
| 196 |                 if (badInputField != null) | 
| 197 |                 { | 
| 198 |                         // Display Message | 
| 199 |                         _application.showMessage("board-size-off-limits", _maxBoardSize); | 
| 200 |                         badInputField.requestFocusInWindow(); | 
| 201 |                         return false; | 
| 202 |                 } | 
| 203 |                 return true; | 
| 204 |         } | 
| 205 |          | 
| 206 |         private void        updateBoard() | 
| 207 |         { | 
| 208 |                 _board.setName(_txfName.getText()); | 
| 209 |                 _board.setDescription(_txfDescription.getText()); | 
| 210 |                 _board.setHeight(((Number) _txfHeight.getValue()).shortValue()); | 
| 211 |                 _board.setWidth(((Number) _txfWidth.getValue()).shortValue()); | 
| 212 |                 _board.setTokenSetter((BoardTokenSetter) _cboTokenSetter.getSelectedItem()); | 
| 213 |   | 
| 214 |                 Set<Integer> participants = new HashSet<Integer>(); | 
| 215 |                 int[] selected = _tblAccounts.getSelectedRows(); | 
| 216 |                 for (int i = 0; i < selected.length; i++) | 
| 217 |                 { | 
| 218 |                         Account account = _accounts.getRow(selected[i]); | 
| 219 |                         participants.add(account.getId()); | 
| 220 |                 } | 
| 221 |                 _board.setParticipants(participants); | 
| 222 |         } | 
| 223 |          | 
| 224 |         private void        refresh() | 
| 225 |         { | 
| 226 |                 _txfName.setText(_board.getName()); | 
| 227 |                 _txfDescription.setText(_board.getDescription()); | 
| 228 |                 _txfWidth.setValue(_board.getWidth()); | 
| 229 |                 _txfHeight.setValue(_board.getHeight()); | 
| 230 |                 _cboTokenSetter.setSelectedItem(_board.getTokenSetter()); | 
| 231 |   | 
| 232 |                 // Remove previous selection first | 
| 233 |                 _tblAccounts.clearSelection(); | 
| 234 |                 // Set new selection | 
| 235 |                 Account[] accounts = _accounts.getRows(); | 
| 236 |                 for (int id: _board.getParticipants()) | 
| 237 |                 { | 
| 238 |                         for (int i = 0; i < accounts.length; i++) | 
| 239 |                         { | 
| 240 |                                 if (accounts[i].getId() == id) | 
| 241 |                                 { | 
| 242 |                                         _tblAccounts.addRowSelectionInterval(i, i); | 
| 243 |                                         break; | 
| 244 |                                 } | 
| 245 |                         } | 
| 246 |                 } | 
| 247 |         } | 
| 248 |   | 
| 249 |         private class ModifyBoardTask extends AbstractTask<Void, Void> | 
| 250 |         { | 
| 251 |                 public ModifyBoardTask(HiveGuiApplicationMain application, GenericDialog parent) | 
| 252 |                 { | 
| 253 |                         super(application, parent); | 
| 254 |                 } | 
| 255 |   | 
| 256 |                 @Override protected Void doInBackground() throws Exception | 
| 257 |                 { | 
| 258 |                         if (_board.getId() == 0) | 
| 259 |                         { | 
| 260 |                                 _service.createBoard(_board); | 
| 261 |                         } | 
| 262 |                         else | 
| 263 |                         { | 
| 264 |                                 _service.modifyBoard(_board); | 
| 265 |                         } | 
| 266 |                         return null; | 
| 267 |                 } | 
| 268 |                  | 
| 269 |                 @Override protected void failed(Throwable cause) | 
| 270 |                 { | 
| 271 |                         if (cause instanceof DuplicateKeyException) | 
| 272 |                         { | 
| 273 |                                 // Display Message | 
| 274 |                                 _application.showMessage("duplicate-board-name", _board.getName()); | 
| 275 |                         } | 
| 276 |                         else | 
| 277 |                         { | 
| 278 |                                 super.failed(cause); | 
| 279 |                         } | 
| 280 |                 } | 
| 281 |         } | 
| 282 |   | 
| 283 |         private final WhiteBoardUserService                _service; | 
| 284 |         private final boolean                                        _create; | 
| 285 |         private final int                                                _maxBoardSize; | 
| 286 |          | 
| 287 |         private final JLabel                                        _lblName = new JLabel(); | 
| 288 |         private final JTextField                                _txfName = new JTextField(); | 
| 289 |         private final JLabel                                        _lblDescription = new JLabel(); | 
| 290 |         private final JTextField                                _txfDescription = new JTextField(); | 
| 291 |         private final JLabel                                        _lblWidth = new JLabel(); | 
| 292 |         private final JFormattedTextField                _txfWidth = new JFormattedTextField( | 
| 293 |                                                                                                 new DecimalFormat("####")); | 
| 294 |         private final JLabel                                        _lblHeight = new JLabel(); | 
| 295 |         private final JFormattedTextField                _txfHeight = new JFormattedTextField( | 
| 296 |                                                                                                 new DecimalFormat("####")); | 
| 297 |         private final JLabel                                        _lblTokenSetter = new JLabel(); | 
| 298 |         private final JComboBox                                        _cboTokenSetter = new JComboBox(); | 
| 299 |         private final JLabel                                        _lblParticipants = new JLabel(); | 
| 300 |         private final BeanTable<Account>                _tblAccounts; | 
| 301 |         private final DataListModel<Account>        _accounts; | 
| 302 | } | 
| 303 | // CSON: ClassDataAbstractionCouplingCheck |