Java圖形界面開發(fā):高級Swing容器(三)
11.5 JViewport類
JViewport很少在JScrollPane之外使用。通常情況下他位于JScrollPane的中間并且使用ViewportLayout管理器來響應在小空間內顯示大Component的定位請求。除了位于JScrollPane的中間以外,JViewport也可以用于JScrollPane的行頭與列頭。
11.5.1 創(chuàng)建JViewport
JViewport只有一個無參數的構造函數:public JViewport()。一旦我們創(chuàng)建了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中的背景色,我們需要設置視圖區(qū)域的背景色:aScrollPane.getViewport().setBackground(newColor)。
視圖的尺寸(viewSize屬性)是基于JViewport內組件的尺寸的(view屬性)。視圖位置(viewPosition屬性)是視圖矩形區(qū)域(viewRect屬性)的左上角,其中矩形區(qū)域的尺寸是視圖區(qū)域的擴展尺寸(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外觀,并沒有實際外觀上的區(qū)別。然而,仍然存在一個JViewport的UIResource相關屬性集合,如表11-12所示。對于JViewport組件,有四個這樣的屬性。

11.6 小結
在本章中,我們探討了一些高級的Swing容器。對于Box類,我們可以更容易的使用BoxLayout管理器考慮到組件的最小尺寸,***尺寸與***尺寸以***的可能方式來創(chuàng)建單行或單列的組件。
對于JSplitPane組件,我們可以通過在其所包含的兩個組件間添加分隔符來創(chuàng)建一行或一列的組件,并允許用戶通過移動分隔符來手動修改組件的尺寸。
JTabbedPane容器每次只顯示所包含的組件集合中的一個組件。所顯示的組件是通過用戶選擇標簽來選擇的,標簽中可以包含具有或是不具有熱鍵的標題,圖標以及工具提示文本。這就是我們通常在程序中見到的流行的屬性頁。
JScrollPane與JViewport容器可以使得我們在一小區(qū)域內顯示一個大組件。JScrollPane添加了滾動條使得終端用戶移動可視化部分,而JViewport沒有添加這些滾動條。
在第12章中,我們將會再次探討Swing庫中的單個組件,包括JProgressBar,JScrollBar以及共享BoundedRangeModel作為其數據模型的JSlider。
原文鏈接:http://blog.csdn.net/mylxiaoyi/article/details/7487194
【編輯推薦】