001/* ---------------------------------------------------------------------------- 002 The Kiwi Toolkit - A Java Class Library 003 Copyright (C) 1998-2004 Mark A. Lindner 004 005 This library is free software; you can redistribute it and/or 006 modify it under the terms of the GNU General Public License as 007 published by the Free Software Foundation; either version 2 of the 008 License, or (at your option) any later version. 009 010 This library is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 General Public License for more details. 014 015 You should have received a copy of the GNU General Public License 016 along with this library; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 018 02111-1307, USA. 019 020 The author may be contacted at: mark_a_lindner@yahoo.com 021 ---------------------------------------------------------------------------- 022 $Log: PathEditor.java,v $ 023 Revision 1.9 2004/05/31 07:52:10 markl 024 partial rewrite to fix some usability problems 025 026 Revision 1.8 2004/03/16 06:43:39 markl 027 LocaleManager method change 028 029 Revision 1.7 2003/01/19 09:46:48 markl 030 replaced JScrollPane instances with KScrollPane. 031 032 Revision 1.6 2001/03/20 00:54:53 markl 033 Fixed deprecated calls. 034 035 Revision 1.5 2001/03/12 09:27:59 markl 036 Source code and Javadoc cleanup. 037 038 Revision 1.4 1999/11/15 03:36:13 markl 039 API fix. 040 041 Revision 1.3 1999/06/28 09:37:13 markl 042 I18N. 043 044 Revision 1.2 1999/01/10 02:56:27 markl 045 added GPL header & RCS tag 046 ---------------------------------------------------------------------------- 047*/ 048 049package kiwi.ui; 050 051import java.awt.*; 052import java.awt.event.*; 053import java.io.*; 054import java.util.*; 055import javax.swing.*; 056import javax.swing.border.*; 057import javax.swing.table.*; 058import javax.swing.event.*; 059 060import kiwi.ui.model.*; 061import kiwi.ui.dialog.*; 062import kiwi.util.*; 063 064/** This class represents a component for editing a path (a list of 065 * directories). It could be used for editing a binary search path, or a 066 * Java classpath, for example. It provides <i>New</i>, <i>Delete</i>, 067 * <i>Move Up</i>, and <i>Move Down</i> buttons. 068 * 069 * <p><center> 070 * <img src="snapshot/PathEditor.gif"><br> 071 * <i>An example PathEditor.</i> 072 * </center> 073 * 074 * @author Mark Lindner 075 */ 076 077public class PathEditor extends KPanel implements ActionListener, 078 ListSelectionListener 079 { 080 private JTable paths; 081 private KButton b_delete, b_up, b_down, b_new; 082 private DefaultTableModel tmodel; 083 private PathListCellEditor cellEditor; 084 private ListSelectionModel sel; 085 private LocaleData loc, loc2; 086 087 /** Construct a new <code>PathEditor</code>. */ 088 089 public PathEditor() 090 { 091 setBackground(SystemColor.control); 092 setLayout(new BorderLayout(5, 5)); 093 094 KPanel panel1 = new KPanel(); 095 panel1.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); 096 097 JToolBar toolBar = new JToolBar(); 098 toolBar.setOpaque(false); 099 toolBar.setFloatable(false); 100 101 ResourceManager rm = KiwiUtils.getResourceManager(); 102 LocaleManager lm = LocaleManager.getDefault(); 103 104 loc = lm.getLocaleData("KiwiDialogs"); 105 loc2 = lm.getLocaleData("KiwiMisc"); 106 107 b_new = new KButton(rm.getIcon("item-new.gif")); 108 b_new.addActionListener(this); 109 b_new.setToolTipText(loc.getMessage("kiwi.tooltip.new")); 110 toolBar.add(b_new); 111 112 b_delete = new KButton(rm.getIcon("delete.gif")); 113 b_delete.addActionListener(this); 114 b_delete.setToolTipText(loc.getMessage("kiwi.tooltip.delete")); 115 b_delete.setEnabled(false); 116 toolBar.add(b_delete); 117 118 b_up = new KButton(rm.getIcon("item-up.gif")); 119 b_up.addActionListener(this); 120 b_up.setToolTipText(loc.getMessage("kiwi.tooltip.move_up")); 121 b_up.setEnabled(false); 122 toolBar.add(b_up); 123 124 b_down = new KButton(rm.getIcon("item-down.gif")); 125 b_down.addActionListener(this); 126 b_down.setToolTipText(loc.getMessage("kiwi.tooltip.move_down")); 127 b_down.setEnabled(false); 128 toolBar.add(b_down); 129 130 panel1.add(toolBar); 131 132 add("North", panel1); 133 134 String[] data = {}; 135 paths = new KTable(); 136 paths.setRowHeight(20); 137 tmodel = new DefaultTableModel(); 138 paths.setModel(tmodel); 139 // paths.setTableHeader(null); 140 paths.setAutoCreateColumnsFromModel(false); 141 paths.setColumnSelectionAllowed(false); 142 paths.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 143 paths.setShowGrid(false); 144 sel = paths.getSelectionModel(); 145 sel.addListSelectionListener(this); 146 Vector v = new Vector(); 147 148 cellEditor = new PathListCellEditor(); 149 150 cellEditor.addActionListener(this); 151 152 tmodel.addColumn(loc.getMessage("kiwi.label.directory_list")); 153 TableColumn col; 154 155 paths.addColumn(col = new TableColumn(0, 100)); 156 col.setCellEditor(cellEditor); 157 158 for(int i = 0; i < data.length; i++) 159 tmodel.addRow(new Object[] { data[i] }); 160 161 KScrollPane scrollPane = new KScrollPane(paths); 162 scrollPane.setBorder(new BevelBorder(BevelBorder.LOWERED)); 163 scrollPane.setBackground(Color.white); 164 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants 165 .VERTICAL_SCROLLBAR_ALWAYS); 166 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants 167 .HORIZONTAL_SCROLLBAR_NEVER); 168 scrollPane.addComponentListener(new ComponentAdapter() 169 { 170 public void componentResized(ComponentEvent ev) 171 { 172 if(paths.isEditing()) 173 paths.getCellEditor().cancelCellEditing(); 174 175 KScrollPane sp = (KScrollPane)ev.getComponent(); 176 Dimension sz = sp.getViewport().getSize(); 177 paths.setSize(sz); 178 } 179 }); 180 181 add("Center", scrollPane); 182 183 setSize(400, 400); 184 } 185 186 /** Handle events. This method is public as an implementation side-effect. */ 187 188 public void actionPerformed(ActionEvent evt) 189 { 190 Object o = evt.getSource(); 191 boolean editing = paths.isEditing(); 192 193 if(o == b_new && !editing) 194 { 195 int i = paths.getRowCount(); 196 tmodel.addRow(new Object[] {""}); // root path??? 197 sel.setSelectionInterval(i, i); 198 paths.editCellAt(i, 0); 199 } 200 else if(o == b_delete && !editing) 201 { 202 int i = paths.getSelectedRow(); 203 204 System.out.println("selected row: " + i); 205 206 if(i < 0) 207 return; 208 if(sel.isSelectionEmpty()) 209 return; 210 211 tmodel.removeRow(i); 212 if(i >= paths.getRowCount()) 213 i = 0; 214 215 sel.setSelectionInterval(i, i); 216 } 217 else if(o == b_up && !editing) 218 { 219 int i = paths.getSelectedRow(); 220 if(i < 1) 221 return; 222 223 tmodel.moveRow(i, i, i - 1); 224 sel.setSelectionInterval(i - 1, i - 1); 225 } 226 else if(o == b_down && !editing) 227 { 228 int i = paths.getSelectedRow(); 229 if(i < 0 || i > (paths.getRowCount() - 2)) 230 return; 231 232 tmodel.moveRow(i, i, i + 1); 233 sel.setSelectionInterval(i + 1, i + 1); 234 } 235 } 236 237 /** Return an array of the paths currently displayed by this view. 238 */ 239 240 public DirectoryPath getDirectoryPath() 241 { 242 int c = tmodel.getRowCount(); 243 String[] paths = new String[c]; 244 for(int i = 0; i < c; i++) 245 paths[i] = (String)tmodel.getValueAt(i, 0); 246 247 return(new DirectoryPath(paths)); 248 } 249 250 /** Set the list of paths to be displayed by this view. 251 */ 252 253 public void setDirectoryPath(DirectoryPath path) 254 { 255 String dirs[] = path.getDirectories(); 256 257 tmodel.setNumRows(0); 258 for(int i = 0; i < dirs.length; i++) 259 tmodel.addRow(new Object[] { dirs[i] }); 260 } 261 262 /* the custom cell editor */ 263 264 private class PathListCellEditor extends AbstractCellEditor 265 implements TableCellEditor, ActionListener 266 { 267 private KPanel jp; 268 private JTextField text; 269 private JButton b_browse; 270 private Vector alisteners; 271 private int row = -1; 272 private KFileChooserDialog d_select = null; 273 private Frame parentFrame; 274 275 PathListCellEditor() 276 { 277 jp = new KPanel(); 278 jp.setLayout(new BorderLayout(2, 2)); 279 280 text = new JTextField(); 281 text.addActionListener(this); 282 jp.add("Center", text); 283 284 b_browse = new KButton(loc.getMessage("kiwi.button.browse") + "..."); 285 b_browse.setMargin(new Insets(0, 2, 0, 2)); 286 b_browse.addActionListener(this); 287 jp.add("East", b_browse); 288 289 alisteners = new Vector(); 290 } 291 292 public Component getTableCellEditorComponent(JTable table, Object value, 293 boolean isSelected, 294 int columnID, int rowIndex) 295 { 296 text.setText((String)value); 297 return(jp); 298 } 299 300 public Object getCellEditorValue() 301 { 302 return(text.getText()); 303 } 304 305 public boolean isCellEditable(EventObject ev) 306 { 307 boolean ok = false; 308 309 if(ev == null) 310 { 311 text.requestFocus(); 312 return(true); 313 } 314 315 MouseEvent mev = (MouseEvent)ev; 316 int newrow = ((JTable)mev.getSource()) 317 .rowAtPoint(new Point(mev.getX(), mev.getY())); 318 319 if(newrow == row) 320 { 321 text.requestFocus(); 322 ok = true; 323 } 324 else 325 row = newrow; 326 327 return(ok); 328 } 329 330 public boolean shouldSelectCell(EventObject evt) 331 { 332// text.requestFocus(); 333 return(true); 334 } 335 336 public boolean stopCellEditing() 337 { 338 // if input is valid... 339 fireEditingStopped(); 340 return(true); 341 } 342 343 public void cancelCellEditing() 344 { 345 fireEditingCanceled(); 346 } 347 348 public void addActionListener(ActionListener l) 349 { 350 alisteners.addElement(l); 351 } 352 353 public void removeActionListener(ActionListener l) 354 { 355 alisteners.removeElement(l); 356 } 357 358 public void actionPerformed(ActionEvent evt) 359 { 360 Object o = evt.getSource(); 361 362 if(o == text) 363 { 364 // if input is valid... 365 fireEditingStopped(); 366 } 367 else if(o == b_browse) 368 { 369 if(d_select == null) 370 { 371 d_select = new KFileChooserDialog(KiwiUtils.getPhantomFrame(), 372 "Directory Selection", 373 KFileChooser.OPEN_DIALOG); 374 375 d_select.setFileSelectionMode(KFileChooser.DIRECTORIES_ONLY); 376 } 377 KiwiUtils.centerWindow(d_select); 378 d_select.setVisible(true); 379 if(!d_select.isCancelled()) 380 { 381 String p = d_select.getSelectedFile().getAbsolutePath(); 382 if(p != null) 383 { 384 text.setText(p); 385 fireEditingStopped(); 386 } 387 } 388 } 389 } 390 } 391 392 public void valueChanged(ListSelectionEvent evt) 393 { 394 boolean empty = sel.isSelectionEmpty(); 395 396 b_up.setEnabled(! empty); 397 b_down.setEnabled(! empty); 398 b_delete.setEnabled(! empty); 399 } 400 401 } 402 403/* end of source file */