现在的位置: 首页 > 综合 > 正文

高级Swing容器(三)

2013年10月10日 ⁄ 综合 ⁄ 共 5789字 ⁄ 字号 评论关闭

11.5 JViewport类

JViewport很少在JScrollPane之外使用。通常情况下他位于JScrollPane的中间并且使用ViewportLayout管理器来响应在小空间内显示大Component的定位请求。除了位于JScrollPane的中间以外,JViewport也可以用于JScrollPane的行头与列头。

11.5.1 创建JViewport

JViewport只有一个无参数的构造函数:public JViewport()。一旦我们创建了JViewport,我们可以通过setView(Component)向其中添加组件。

11.5.2 JViewport属性

表11-10显示了JViewport的13个属性。将布局管理器设置为ViewportLayout以外的布局管理也可以的,但是并不推荐,因为ViewportLayout布局管理器可以使得JViewport正确工作。

由于滚动的复杂性以及性能原因,JViewport并不支持边框。试着使用setBorder(Border)方法将边框设置为非null会抛出IllegalArgumentException。因为没有边框,所以insets属性的设置总为(0,0,0,0)。我们不能在JViewport周围显示边框,但是我们可以在视图所在的组件周围显示边框。只需要简单的在组件周围放置一个边框,或是将组件放在一个具有边框的JPanel中,然后将其添加到JViewport。如果我们确实在组件周围添加了边框,只有当组件部分可以见时边框才可见。如果我们不希望边框滚动,我们必须将JViewport放在类似JScrollPane这样具有自己边框的组件中。

提示,要设置显示在JScrollPane中的背景色,我们需要设置视图区域的背景色:aScrollPane.getViewport().setBackground(newColor)。

视图的尺寸(viewSize属性)是基于JViewport内组件的尺寸的(view属性)。视图位置(viewPosition属性)是视图矩形区域(viewRect属性)的左上角,其中矩形区域的尺寸是视图区域的扩展尺寸(extentSize属性)。如果感到迷惑,图11-18会有助于我们理解JViewport中的各种属性。

scrollMode属性可以设置为表11-11中所列的类常量的一个。在大多数情况下,我们可以使用默认的BLIST_SCROLL_MODE模式。

为了在周围移动视图的可见部分,我们只需要修改viewPosition属性。这会移动viewRect,使得我们可以看到视图的不同部分。为了显示这一行为,列表11-5中的程序将键盘快捷键绑定到了JViewport,从而我们可以使用箭头键来移动视图。(通常情况下,JScrollPane会获得这些键盘动作。)代码的主要部分对于设置相应的输入/动作映射是必须的。以粗体显示的代码是移动视图所必须的。

package swingstudy.ch11;
 
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.ActionEvent;
 
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JViewport;
import javax.swing.KeyStroke;
 
public class MoveViewSample {
 
	public static final int INCREASE = 0; // direction
	public static final int DECREASE = 1; // direction
	public static final int X_AXIS = 0;	// axis
	public static final int Y_AXIS = 1;	// axis
	public static final int UNIT = 0; 	// type
	public static final int BLOCK = 1;	// type
 
	static class MoveAction extends AbstractAction {
		JViewport viewport;
		int direction;
		int axis;
		int type;
		public MoveAction(JViewport viewport, int direction, int axis, int type) {
			if(viewport == null) {
				throw new IllegalArgumentException("null viewport not permitted");
			}
			this.viewport = viewport;
			this.direction = direction;
			this.axis = axis;
			this.type = type;
		}
 
		public void actionPerformed(ActionEvent event) {
			Dimension extentSize = viewport.getExtentSize();
			int horizontalMoveSize = 0;
			int verticalMoveSize = 0;
			if(axis == X_AXIS) {
				if(type == UNIT) {
					horizontalMoveSize = 1;
				}
				else {
					// type == BLOCK
					horizontalMoveSize = extentSize.width;
				}
			}
			else {
				// axis == Y_AXIS
				if(type == UNIT) {
					verticalMoveSize = 1;
				}
				else {
					// type = BLOCK
					verticalMoveSize = extentSize.height;
				}
			}
			if(direction == DECREASE) {
				horizontalMoveSize = -horizontalMoveSize;
				verticalMoveSize = -verticalMoveSize;
			}
			// translate origin by some amount
			Point origin = viewport.getViewPosition();
			origin.x += horizontalMoveSize;
			origin.y += verticalMoveSize;
			// set new viewing origin
			viewport.setViewPosition(origin);
		}
	}
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
 
		Runnable runner = new Runnable() {
			public void run() {
				JFrame frame = new JFrame("JViewport Sample");
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				Icon icon = new ImageIcon("dog.jpg");
				JLabel dogLabel = new JLabel(icon);
				JViewport viewport =  new JViewport();
				viewport.setView(dogLabel);
 
				InputMap inputMap = viewport.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
				ActionMap actionMap = viewport.getActionMap();
 
				// up key moves view up unit
				Action upKeyAction = new MoveAction(viewport, DECREASE, Y_AXIS, UNIT);
				KeyStroke upKey = KeyStroke.getKeyStroke("UP");
				inputMap.put(upKey, "up");
				actionMap.put("up", upKeyAction);
 
				// down key moves view down unit
				Action downKeyAction = new MoveAction(viewport, INCREASE, Y_AXIS, UNIT);
				KeyStroke downKey = KeyStroke.getKeyStroke("DOWN");
				inputMap.put(downKey, "down");
				actionMap.put("down", downKeyAction);
 
				// left key moves view left unit
				Action leftKeyAction = new MoveAction(viewport, DECREASE, X_AXIS, UNIT);
				KeyStroke leftKey = KeyStroke.getKeyStroke("LEFT");
				inputMap.put(leftKey, "left");
				actionMap.put("left", leftKeyAction);
 
				// right key mvoes view right unit
				Action rightKeyAction = new MoveAction(viewport, INCREASE, X_AXIS, UNIT);
				KeyStroke rightKey = KeyStroke.getKeyStroke("RIGHT");
				inputMap.put(rightKey, "right");
				actionMap.put("right", rightKeyAction);
 
				// pgup key moves view up block
				Action pgUpKeyAction = new MoveAction(viewport, DECREASE, Y_AXIS, BLOCK);
				KeyStroke pgUpKey = KeyStroke.getKeyStroke("PAGE_UP");
				inputMap.put(pgUpKey, "pgUp");
				actionMap.put("pgUp", pgUpKeyAction);
 
				// pgdn key moves view down block
				Action pgDnKeyAction = new MoveAction(viewport, INCREASE, Y_AXIS, BLOCK);
				KeyStroke pgDnKey = KeyStroke.getKeyStroke("PAGE_DOWN");
				inputMap.put(pgDnKey, "pgDn");
				actionMap.put("pgDn", pgDnKeyAction);
 
				// shift-pgup key moves view left block
				Action shiftPgUpKeyAction = new MoveAction(viewport, DECREASE, X_AXIS, BLOCK);
				KeyStroke shiftPgUpKey = KeyStroke.getKeyStroke("shift PAGE_UP");
				inputMap.put(shiftPgUpKey, "shiftPgUp");
				actionMap.put("shiftPgUp", shiftPgUpKeyAction);
 
				// shift-pgdn key moves view right block
				Action shiftPgDnKeyAction = new MoveAction(viewport, INCREASE, X_AXIS, BLOCK);
				KeyStroke shiftPgDnKey = KeyStroke.getKeyStroke("shift PAGE_DOWN");
				inputMap.put(shiftPgDnKey, "shiftPgDn");
				actionMap.put("shiftPgDn", shiftPgDnKeyAction);
 
				frame.add(viewport, BorderLayout.CENTER);
				frame.setSize(300, 200);
				frame.setVisible(true);
			}
		};
		EventQueue.invokeLater(runner);
	}
 
}

11.5.3 自定义JViewport观感

每一个可安装的Swing观感通过BasicViewportUI共享相同的JViewport外观,并没有实际外观上的区别。然而,仍然存在一个JViewport的UIResource相关属性集合,如表11-12所示。对于JViewport组件,有四个这样的属性。

11.6 小结

在本章中,我们探讨了一些高级的Swing容器。对于Box类,我们可以更容易的使用BoxLayout管理器考虑到组件的最小尺寸,最优尺寸与最大尺寸以最好的可能方式来创建单行或单列的组件。

对于JSplitPane组件,我们可以通过在其所包含的两个组件间添加分隔符来创建一行或一列的组件,并允许用户通过移动分隔符来手动修改组件的尺寸。

JTabbedPane容器每次只显示所包含的组件集合中的一个组件。所显示的组件是通过用户选择标签来选择的,标签中可以包含具有或是不具有热键的标题,图标以及工具提示文本。这就是我们通常在程序中见到的流行的属性页。

JScrollPane与JViewport容器可以使得我们在一小区域内显示一个大组件。JScrollPane添加了滚动条使得终端用户移动可视化部分,而JViewport没有添加这些滚动条。

在第12章中,我们将会再次探讨Swing库中的单个组件,包括JProgressBar,JScrollBar以及共享BoundedRangeModel作为其数据模型的JSlider。

抱歉!评论已关闭.