Coverage report

  %line %branch
tsukuba_bunko.peko.canvas.select.SelectCanvas
0% 
0% 

 1  
 /*
 2  
  * All Rights Reserved.
 3  
  * Copyright (C) 1999-2005 Tsukuba Bunko.
 4  
  *
 5  
  * Licensed under the BSD License ("the License"); you may not use
 6  
  * this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *       http://www.tsukuba-bunko.org/licenses/LICENSE.txt
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  *
 17  
  * $Id: SelectCanvas.java,v 1.3 2005/07/24 20:55:57 ppoi Exp $
 18  
  */
 19  
 package tsukuba_bunko.peko.canvas.select;
 20  
 
 21  
 import	java.awt.Dimension;
 22  
 
 23  
 import	java.awt.event.KeyEvent;
 24  
 import	java.awt.event.KeyListener;
 25  
 
 26  
 import	java.util.List;
 27  
 import	java.util.Map;
 28  
 
 29  
 import	javax.swing.JComponent;
 30  
 
 31  
 import	tsukuba_bunko.peko.ActionControler;
 32  
 import	tsukuba_bunko.peko.Logger;
 33  
 import	tsukuba_bunko.peko.PekoSystem;
 34  
 
 35  
 
 36  
 /**
 37  
  * 選択肢を表示するキャンバスです。
 38  
  * @author	$Author: ppoi $
 39  
  * @version	$Revision: 1.3 $
 40  
  */
 41  
 public class SelectCanvas	extends JComponent	implements KeyListener	{
 42  
 
 43  
 	/**
 44  
 	 * serial version UID
 45  
 	 */
 46  
 	private static final long	serialVersionUID	= 103943516971774006L;
 47  
 
 48  
 	/**
 49  
 	 * ボタンの位置:左寄せ
 50  
 	 */
 51  
 	public static final int	ALIGN_LEFT = 0;
 52  
 
 53  
 	/**
 54  
 	 * ボタンの位置:中央
 55  
 	 */
 56  
 	public static final int	ALIGN_CENTER = 1;
 57  
 
 58  
 	/**
 59  
 	 * ボタンの位置:右寄せ
 60  
 	 */
 61  
 	public static final int	ALIGN_RIGHT = 2;
 62  
 
 63  
 	/**
 64  
 	 * ボタンの位置:上
 65  
 	 */
 66  
 	public static final int	VALIGN_TOP = 0;
 67  
 
 68  
 	/**
 69  
 	 * ボタンの位置:中央
 70  
 	 */
 71  
 	public static final int	VALIGN_MIDDLE = 1;
 72  
 
 73  
 	/**
 74  
 	 * ボタンの位置:下
 75  
 	 */
 76  
 	public static final int	VALIGN_BOTTOM = 2;
 77  
 
 78  
 
 79  
 	/**
 80  
 	 * 有効フラグ
 81  
 	 */
 82  0
 	private boolean	_active = false;
 83  
 
 84  
 	/**
 85  
 	 * 選択肢リスト
 86  
 	 */
 87  0
 	private List	_buttons = null;
 88  
 
 89  
 	/**
 90  
 	 * 選択された ID
 91  
 	 */
 92  0
 	private String	_id = null;
 93  
 
 94  
 	/**
 95  
 	 * 現在選択中のボタン
 96  
 	 */
 97  0
 	private SelectItemButton	_selected = null;
 98  
 
 99  
 	/**
 100  
 	 * 現在選択中のボタンのインデックス
 101  
 	 */
 102  0
 	private int	_selectedIndex = -1;
 103  
 
 104  
 
 105  
 	/**
 106  
 	 * 最後に押されたキーのキーコード
 107  
 	 */
 108  0
 	private int	_lastKeyCode = -1;
 109  
 
 110  
 
 111  
 	/**
 112  
 	 * 選択肢ボタンの配置位置
 113  
 	 */
 114  0
 	private int	_align = SelectCanvas.ALIGN_CENTER;
 115  
 
 116  
 	/**
 117  
 	 */
 118  0
 	private int	_verticalAlign = SelectCanvas.VALIGN_TOP;
 119  
 
 120  
 	/**
 121  
 	 * 選択肢の列数
 122  
 	 */
 123  0
 	private int	_columns = 1;
 124  
 
 125  
 	/**
 126  
 	 * 列間
 127  
 	 */
 128  0
 	private int	_columnSpan = 20;
 129  
 
 130  
 	/**
 131  
 	 * 行間
 132  
 	 */
 133  0
 	private int	_rowSpan = 20;
 134  
 
 135  
 	/**
 136  
 	 * 境界線とルートキャンバスの枠との間
 137  
 	 */
 138  0
 	private int	_boundSpan = 20;
 139  
 
 140  
 	/**
 141  
 	 * ボタンスタイルマップ
 142  
 	 */
 143  0
 	private Map	_buttonStyle = null;
 144  
 
 145  
 	/**
 146  
 	 * Dimension cache
 147  
 	 */
 148  0
 	private Dimension	_dimensionCache = null;
 149  
 
 150  
 
 151  
 	/**
 152  
 	 * <code>SelectCanvas</code> のインスタンスを作成します。
 153  
 	 */
 154  
 	public SelectCanvas()
 155  
 	{
 156  0
 		super();
 157  0
 	}
 158  
 
 159  
 
 160  
 	/**
 161  
 	 * 選択肢ボタンの配置位置を設定します。設定した内容は、次回選択指表示時から反映されます。
 162  
 	 * @param	align	配置位置
 163  
 	 * @throws	IllegalArgumentException	align が {@link SelectCanvas#ALIGN_CENTER} または {@link SelectCanvas#ALIGN_LEFT} または {@link SelectCanvas#ALIGN_RIGHT} 以外の場合。
 164  
 	 */
 165  
 	public void setAlignment( int align )
 166  
 	{
 167  0
 		if( (align == SelectCanvas.ALIGN_CENTER) || (align == SelectCanvas.ALIGN_LEFT) || (align == SelectCanvas.ALIGN_RIGHT) )	{
 168  0
 			_align = align;
 169  0
 		}
 170  
 		else	{
 171  0
 			throw new IllegalArgumentException( "invalid alignment type is specified." );
 172  
 		}
 173  0
 	}
 174  
 
 175  
 	/**
 176  
 	 * 選択肢ボタンの配置位置を取得します。
 177  
 	 * @return	選択肢ボタンの配置位置
 178  
 	 */
 179  
 	public int getAlignment()
 180  
 	{
 181  0
 		return _align;
 182  
 	}
 183  
 
 184  
 	/**
 185  
 	 * 選択肢ボタンの垂直方向の配置位置を設定します。
 186  
 	 * @param	valign	配置位置
 187  
 	 * @throws	IllegalArgumentException	align が {@link SelectCanvas#VALIGN_TOP} または {@link SelectCanvas#VALIGN_MIDDLE} または {@link SelectCanvas#VALIGN_BOTTOM} 以外の場合。
 188  
 	 */
 189  
 	public void setVerticalAlignment( int valign )
 190  
 	{
 191  0
 		if( (valign == SelectCanvas.ALIGN_CENTER) || (valign == SelectCanvas.ALIGN_LEFT) || (valign == SelectCanvas.ALIGN_RIGHT) )	{
 192  0
 			_verticalAlign = valign;
 193  0
 		}
 194  
 		else	{
 195  0
 			throw new IllegalArgumentException( "invalid vertical alignment type is specified." );
 196  
 		}
 197  0
 	}
 198  
 
 199  
 	/**
 200  
 	 * 選択肢ボタンの垂直方向の配置位置を取得します。
 201  
 	 * @return	選択肢ボタンの配置位置
 202  
 	 */
 203  
 	public int getVericalAlignment()
 204  
 	{
 205  0
 		return _verticalAlign;
 206  
 	}
 207  
 
 208  
 	/**
 209  
 	 * 選択肢ボタンの列数を設定します。設定した内容は、次回選択指表示時から反映されます。
 210  
 	 * @param	columns 列数
 211  
 	 * @throws	IllegalArgumentException	<code>columns <= 0</code> の場合
 212  
 	 */
 213  
 	public void setColumns( int columns )
 214  
 	{
 215  0
 		_columns = columns;
 216  0
 	}
 217  
 
 218  
 	/**
 219  
 	 * 選択肢ボタンの列数を取得します。
 220  
 	 * @return	選択肢ボタンの列数
 221  
 	 */
 222  
 	public int getColumns()
 223  
 	{
 224  0
 		return _columns;
 225  
 	}
 226  
 
 227  
 	/**
 228  
 	 * 列間を設定します。設定した内容は、次回選択指表示時から反映されます。
 229  
 	 * @param	span	列間の長さ
 230  
 	 */
 231  
 	public void setColumnSpan( int span )
 232  
 	{
 233  0
 		_columnSpan = span;
 234  0
 	}
 235  
 
 236  
 	/**
 237  
 	 * 列間を取得します。
 238  
 	 * @return	列間の長さ
 239  
 	 */
 240  
 	public int getColumnSpan()
 241  
 	{
 242  0
 		return _columnSpan;
 243  
 	}
 244  
 
 245  
 	/**
 246  
 	 * 行間を設定します。設定した内容は、次回選択指表示時から反映されます。
 247  
 	 * @param	span	行間の長さ
 248  
 	 */
 249  
 	public void setRowSpan( int span )
 250  
 	{
 251  0
 		_rowSpan = span;
 252  0
 	}
 253  
 
 254  
 	/**
 255  
 	 * 行間を取得します。
 256  
 	 * @return	行間の長さ
 257  
 	 */
 258  
 	public int getRowSpan()
 259  
 	{
 260  0
 		return _rowSpan;
 261  
 	}
 262  
 
 263  
 	/**
 264  
 	 * 選択肢領域の境界線とルートキャンバスの枠との間を設定します。設定した内容は、次回選択指表示時から反映されます。
 265  
 	 * @param	span	行間の長さ
 266  
 	 */
 267  
 	public void setBoundSpan( int span )
 268  
 	{
 269  0
 		_boundSpan = span;
 270  0
 	}
 271  
 
 272  
 	/**
 273  
 	 * 選択肢領域の境界線とルートキャンバスの枠との間を取得します。
 274  
 	 * @return	行間の長さ
 275  
 	 */
 276  
 	public int getBoundSpan()
 277  
 	{
 278  0
 		return _boundSpan;
 279  
 	}
 280  
 
 281  
 	/**
 282  
 	 * 選択肢ボタンのスタイルを設定します。設定した内容は、次回選択指表示時から反映されます。
 283  
 	 * @param	styles	選択肢ボタンのスタイルマップ
 284  
 	 */
 285  
 	public void setButtonStyle( Map styles )
 286  
 	{
 287  0
 		_buttonStyle = styles;
 288  0
 	}
 289  
 
 290  
 	/**
 291  
 	 * 選択肢ボタンのスタイルを取得します。
 292  
 	 * @return	選択肢ボタンのスタイル
 293  
 	 */
 294  
 	public Map getButtonStyle()
 295  
 	{
 296  0
 		return _buttonStyle;
 297  
 	}
 298  
 
 299  
 	/**
 300  
 	 * 選択肢を表示し、ユーザーが選択した選択肢の ID を取得します。
 301  
 	 * @param	selectItems	選択肢
 302  
 	 * @return	選択された選択肢の ID
 303  
 	 */
 304  
 	public String select( List selectItems )
 305  
 	{
 306  0
 		return select( selectItems, -1 );
 307  
 	}
 308  
 
 309  
 	/**
 310  
 	 * 選択肢を表示し、ユーザーが選択した選択肢の ID を取得します。
 311  
 	 * @param	selectItems	選択肢
 312  
 	 * @param	timeout	タイムアウトするまでの時間[ms]
 313  
 	 * @return	選択された選択肢の ID
 314  
 	 */
 315  
 	public String select( List selectItems, long timeout )
 316  
 	{
 317  0
 		if( _buttonStyle == null )	{
 318  0
 			throw new IllegalStateException( "button styles is not specified." );
 319  
 		}
 320  
 
 321  0
 		if( _active )	{
 322  0
 			Logger.debug( "[canvas.select] already show selection." );
 323  0
 			return null;
 324  
 		}
 325  
 
 326  0
 		synchronized( this )	{
 327  0
 			_id = null;
 328  
 
 329  0
 			Dimension	canvasSize = getSize( _dimensionCache );
 330  
 
 331  0
 			int	size = selectItems.size();
 332  0
 			int	buttonWidth = 320;
 333  0
 			Integer	intValue = (Integer)_buttonStyle.get( SelectItemButton.STYLE_WIDTH );
 334  0
 			if( intValue != null )	{
 335  0
 				buttonWidth = intValue.intValue();
 336  
 			}
 337  
 
 338  0
 			setVisible( false );
 339  
 
 340  0
 			SelectItem	item = null;
 341  0
 			SelectItemButton	button = null;
 342  0
 			List	buttons = new java.util.ArrayList( size );
 343  0
 			int	x = 0;
 344  0
 			int	y = 0;
 345  0
 			int	rowHeight = 0;
 346  0
 			Dimension	buttonSize = new Dimension( 0, 0 );
 347  0
 			for( int i = 0; i < size; ++i )	{
 348  0
 				if( (i % _columns) == 0 )	{
 349  0
 					y += rowHeight;
 350  0
 					if( item != null )	{
 351  0
 						y += _rowSpan;
 352  
 					}
 353  0
 					x = 0;
 354  0
 					rowHeight = 0;
 355  0
 				}
 356  
 				else	{
 357  0
 					x += (buttonSize.width + _columnSpan);
 358  
 				}
 359  
 
 360  0
 				item = (SelectItem)selectItems.get( i );
 361  0
 				button = new SelectItemButton( this );
 362  0
 				button.setSelectItem( item );
 363  0
 				button.prepare( _buttonStyle );
 364  0
 				buttons.add( button );
 365  
 
 366  0
 				add( button );
 367  0
 				button.setLocation( x, y );
 368  0
 				buttonSize = button.getSize( buttonSize );
 369  0
 				if( buttonSize.height > rowHeight )	{
 370  0
 					rowHeight = buttonSize.height;
 371  
 				}
 372  
 			}
 373  
 
 374  0
 			int	areaWidth = (buttonWidth * _columns) + (_columnSpan * (_columns - 1));
 375  0
 			int	leftPosition = 0;
 376  0
 			if( areaWidth > canvasSize.width )	{
 377  0
 				leftPosition = 0;
 378  0
 			}
 379  0
 			else if( (areaWidth + _boundSpan) > canvasSize.width )	{
 380  0
 				leftPosition = (canvasSize.width - areaWidth) / 2;
 381  0
 			}
 382  0
 			else if( _align == SelectCanvas.ALIGN_CENTER )	{
 383  0
 				leftPosition = (canvasSize.width - areaWidth) / 2;
 384  0
 			}
 385  0
 			else if( _align == SelectCanvas.ALIGN_LEFT )	{
 386  0
 				leftPosition = _boundSpan;
 387  0
 			}
 388  0
 			else if( _align == SelectCanvas.ALIGN_RIGHT )	{
 389  0
 				leftPosition = canvasSize.width - areaWidth - _boundSpan;
 390  
 			}
 391  
 
 392  0
 			int	areaHeight = y + rowHeight;
 393  0
 			int	topPosition = 0;
 394  0
 			if( areaHeight > canvasSize.height )	{
 395  0
 				topPosition = 0;
 396  0
 			}
 397  0
 			else if( (areaHeight + _boundSpan) > canvasSize.height )	{
 398  0
 				topPosition = (canvasSize.height - areaHeight) / 2;
 399  0
 			}
 400  0
 			else if( _verticalAlign == SelectCanvas.VALIGN_TOP )	{
 401  0
 				topPosition = _boundSpan;
 402  0
 			}
 403  0
 			else if( _verticalAlign == SelectCanvas.VALIGN_MIDDLE )	{
 404  0
 				topPosition = (canvasSize.height - areaHeight) / 2;
 405  0
 			}
 406  0
 			else if( _verticalAlign == SelectCanvas.VALIGN_BOTTOM )	{
 407  0
 				topPosition = canvasSize.height - areaHeight - _boundSpan;
 408  
 			}
 409  0
 			setLocation( leftPosition, topPosition );
 410  
 
 411  0
 			_buttons = buttons;
 412  0
 			_active = true;
 413  
 
 414  0
 			setVisible( true );
 415  0
 		}
 416  
 
 417  0
 		Logger.debug( "[canvas.select] wait for selecting." );
 418  0
 		ActionControler	controler = PekoSystem.getInstance().getActionControler();
 419  0
 		if( timeout > 0 )	{
 420  0
 			controler.stop( timeout );
 421  0
 		}
 422  
 		else	{
 423  0
 			controler.stop();
 424  
 		}
 425  
 
 426  0
 		synchronized( this )	{
 427  0
 			int	size = _buttons.size();
 428  0
 			for( int i = 0; i < size; ++i )	{
 429  0
 				remove( (SelectItemButton)_buttons.get(i) );
 430  
 			}
 431  0
 			_buttons.clear();
 432  0
 			_buttons = null;
 433  0
 		}
 434  
 
 435  0
 		Logger.debug( "[canvas.select] id: " + _id );
 436  0
 		return _id;
 437  
 	}
 438  
 
 439  
 	/**
 440  
 	 * 選択肢の選択待ちを解除します。
 441  
 	 */
 442  
 	public void cancel()
 443  
 	{
 444  0
 		_active = false;
 445  0
 		synchronized( this )	{
 446  0
 			if( _buttons != null )	{
 447  0
 				_id = null;
 448  0
 				ActionControler	controler = PekoSystem.getInstance().getActionControler();
 449  0
 				controler.start();
 450  0
 				Logger.debug( "[cenvas.select] canceled." );
 451  
 			}
 452  0
 		}
 453  0
 	}
 454  
 
 455  
 
 456  
 //
 457  
 //	選択イベント処理
 458  
 //
 459  
 	/**
 460  
 	 * <code>button</code> が選択状態になりました。
 461  
 	 * @param	button	選択状態になった SelectItemButton インスタンス
 462  
 	 */
 463  
 	public void itemSelecting( SelectItemButton button )
 464  
 	{
 465  0
 		SelectItemButton	old = _selected;
 466  0
 		_selected = button;
 467  0
 		if( (old != null) && (old != button) )	{
 468  0
 			old.setSelected( false );
 469  
 		}
 470  0
 		_selectedIndex = _buttons.indexOf( button );
 471  0
 	}
 472  
 
 473  
 	/**
 474  
 	 * <code>button</code> が非選択状態になりました
 475  
 	 * @param	button	非選択状態になった SelectItemButton インスタンス
 476  
 	 */
 477  
 	public void itemDeselected( SelectItemButton button )
 478  
 	{
 479  0
 		if( _selected == button )	{
 480  0
 			_selected = null;
 481  0
 			_selectedIndex = -1;
 482  
 		}
 483  0
 	}
 484  
 
 485  
 	/**
 486  
 	 * <code>button</code> が選択されました。
 487  
 	 * @param	button	選択された SelectItemButton インスタンス
 488  
 	 */
 489  
 	public void itemSelected( SelectItemButton button )
 490  
 	{
 491  0
 		if( _active )	{
 492  0
 			synchronized( this )	{
 493  0
 				if( _active )	{
 494  0
 					_selected = null;
 495  0
 					_selectedIndex = -1;
 496  0
 					_id = button.getSelectItem().getID();
 497  0
 					_active = false;
 498  0
 					Logger.debug( "[canvas.select] selected: " + _id );
 499  0
 					ActionControler	controler = PekoSystem.getInstance().getActionControler();
 500  0
 					controler.start();
 501  
 				}
 502  0
 			}
 503  
 		}
 504  0
 	}
 505  
 
 506  
 
 507  
 //
 508  
 //	KeyListener の実装
 509  
 //
 510  
 	public void keyPressed( KeyEvent ev )
 511  
 	{
 512  0
 		if( _active )	{
 513  0
 			int	code = ev.getKeyCode();
 514  0
 			if( _lastKeyCode == -1 )	{
 515  0
 				_lastKeyCode = code;
 516  0
 			}
 517  0
 			else if( _lastKeyCode != code )	{
 518  0
 				_lastKeyCode = -1;
 519  
 			}
 520  
 
 521  0
 			int	index = _selectedIndex;
 522  0
 			int	size = _buttons.size();
 523  
 
 524  0
 			if( code == KeyEvent.VK_DOWN )	{
 525  0
 				index = (index + 1) % size;
 526  0
 			}
 527  0
 			else if( (code == KeyEvent.VK_RIGHT) && (_columns > 1) )	{
 528  0
 				index = (index + 1) % size;
 529  0
 			}
 530  0
 			else if( code == KeyEvent.VK_UP )	 {
 531  0
 				index--;
 532  0
 				if( index < 0 )	{
 533  0
 					index = _buttons.size() -1 ;
 534  0
 				}
 535  
 			}
 536  0
 			else if( (code == KeyEvent.VK_LEFT) && (_columns > 1) )	{
 537  0
 				index--;
 538  0
 				if( index < 0 )	{
 539  0
 					index = _buttons.size() -1 ;
 540  0
 				}
 541  
 			}
 542  
 			else	{
 543  0
 				return;
 544  
 			}
 545  0
 			SelectItemButton	button = (SelectItemButton)_buttons.get( index );
 546  0
 			button.setSelected( true );
 547  
 		}
 548  0
 	}
 549  
 
 550  
 	public void keyReleased( KeyEvent ev )
 551  
 	{
 552  0
 		if( !_active || (_buttons == null) )	{
 553  0
 			return;
 554  
 		}
 555  
 
 556  0
 		int	code = ev.getKeyCode();
 557  0
 		if( code != _lastKeyCode )	{
 558  0
 			_lastKeyCode = -1;
 559  0
 			return;
 560  
 		}
 561  
 
 562  0
 		if( (code == KeyEvent.VK_ENTER) && (_selected != null) )	{
 563  0
 			itemSelected( _selected );
 564  
 		}
 565  0
 		_lastKeyCode = -1;
 566  0
 	}
 567  
 
 568  
 	public void keyTyped( KeyEvent ev )
 569  
 	{
 570  0
 	}
 571  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.