Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1476344
  • 博文数量: 295
  • 博客积分: 10051
  • 博客等级: 上将
  • 技术积分: 3850
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-11 08:50
文章分类

全部博文(295)

文章存档

2011年(1)

2009年(4)

2008年(290)

我的朋友

分类: Java

2008-04-17 15:40:19

第13章 滚动

  本章介绍Swing的滚动体系结构,这个体系结构包括两个轻量Swing容器、一个Scrollable接口、和一个JScrollBar类。其中,这两个轻量Swing容器是JViewport和JScrollPane,设计这个Scrollable接口来支持有特殊滚动需求的组件。
  JViewport实例很少被实例化,也很少被直接使用,然而,本章仍将用相当大的篇幅来介绍JViewport类,因为它是Swing滚动体系结构的基础组件。
  设计JScrollPane组件来替代AWT的重量组件ScrollPane。JScrollPane在AWT的ScrollPane基础上做了许多改进,包括具有配置行头部的能力和具有指定在滚动窗格角部组件的能力。
  Scrollable接口是为表格、树、文本组件和列表等包含数据行或数据列的可滚动组件而设计的。
  JScrollBar组件是一个用来实现手动滚动的滚动条。虽然Swing的JScrollPane组件在大多数滚动情况是足够用了,但是,有时为了性能或资源的考,还必须实现手动滚动。在这种情况下,可以用JScrollBar组件来滚动容器的内容。

13.1 JViewport

  JViewport类是Swing滚动体系结构的基础。就如它的名字所指出的那样,JViewport的实例提供一个视口,视图的特定区域可以显示在这个视口中。可以操纵由视口显示的视图的位置,以便在不同的时刻,使不同的视图区域出现在这个视口中。
  图13-1所示的小应用程序包含JViewport的一个实例,它的视图是JLabel的一个实例。该标签配备了一幅比显示图像的视口还要大的图像。这个小应用程序提供了四个用于调整视口中视图位置的按钮。
  图13-1中的左图显示这个小应用程序开始时的样子。右图显示出在反复激活up和left按钮后,这个小应用程序的梯子。应该强调的是,反复激活按钮不是滚动视口中视图最理想的方式,但是它说明了一个视口是怎样调整其视图位置的。
  这个小应用程序创建JViewport的一个实例和JLabel的一个实例。通过调用JVieweport.setView()来指定这个标签作为视口的视图。这个小应用程序还创建了一个ControlPanel实例(它是JPanel的一个扩展),这个实例包含了四个用于滚动标签的按钮。

例13-1 用JViewport的一个实例来滚动一幅图像


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JViewport viewport = new JViewport();
JPanel view = new JPanel();

view.add(new JLabel(
new ImageIcon("anjinAndMariko.gif")));

viewport.setView(view);

contentPane.add(new ControlPanel(viewport),
BorderLayout.NORTH);
contentPane.add(viewport, BorderLayout.CENTER);
}
}
class ControlPanel extends JPanel {
private JViewport viewport;

private JButton[] buttons = {
new JButton("up"), new JButton("down"),
new JButton("left"), new JButton("right")
};

public ControlPanel(JViewport vp) {
viewport = vp;

for(int i=0; i < buttons.length; ++i) {
add(buttons[i]);

buttons[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
scroll(e.getActionCommand());
}
});
}
}
private void scroll(String actionCmd) {
Point vp = viewport.getViewPosition();

if(actionCmd.equals("up")) vp.y += 5;
else if(actionCmd.equals("down")) vp.y -= 5;
else if(actionCmd.equals("left")) vp.x += 5;
else if(actionCmd.equals("right")) vp.x -= 5;

viewport.setViewPosition(vp);
}
}


13.1.1 拖动视口中的视图

 

例13-2 拖动视口中的视图


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JLabel label = new JLabel(new ImageIcon("pic.gif"));
JViewport vp = new JViewport();
ViewportDragListener listener =
new ViewportDragListener(vp);

vp.setView(label);
vp.addMouseListener(listener);
vp.addMouseMotionListener(listener);

contentPane.add(vp, BorderLayout.CENTER);
}
}
class ViewportDragListener extends MouseAdapter
implements MouseMotionListener {
private JViewport viewport;
private Point last = new Point(), scrollTo = new Point();

public ViewportDragListener(JViewport viewport) {
this.viewport = viewport;
}
public void mousePressed(MouseEvent e) {
last.x = e.getPoint().x;
last.y = e.getPoint().y;
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
Point drag = e.getPoint();
Point viewPos = viewport.getViewPosition();
Point offset = new Point(drag.x-last.x, drag.y-last.y);
last.x = drag.x;
last.y = drag.y;

if(viewport.contains(drag)) {
scrollTo.x = viewPos.x - offset.x;
scrollTo.y = viewPos.y - offset.y;
viewport.setViewPosition(scrollTo);
}
}
}


13.1.2 使用scrollRectToVisible

 

例13-3 使用scrollRectToVisible()


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
private JButton buttons[] = {
new JButton(), new JButton(), new JButton(),
new JButton(), new JButton(), new JButton(),
new JButton(), new JButton(), new JButton(),
new JButton(), new JButton(), new JButton(),
new JButton(), new JButton(), new JButton(),
new JButton(), new JButton(), new JButton(),
};
public Test() {
Container contentPane = getContentPane();
JViewport viewport = new JViewport();
JPanel view = new JPanel();
JPanel controlPanel = new ControlPanel(buttons);

view.setLayout(new GridLayout(0,3));

for(int i=0; i < buttons.length; ++i) {
buttons[i].setText("button # " + i);
buttons[i].setPreferredSize(new Dimension(150,50));
view.add(buttons[i]);
}

viewport.setView(view);

contentPane.add(controlPanel, BorderLayout.NORTH);
contentPane.add(viewport, BorderLayout.CENTER);
}
}
class ControlPanel extends JPanel {
private JComboBox combo = new JComboBox();

public ControlPanel(final JButton[] buttons) {
add(combo);

for(int i=0; i < buttons.length; ++i) {
combo.addItem("button number " + i);
}
combo.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
int index = combo.getSelectedIndex();
JButton button = buttons[index];
Dimension size = button.getSize();

buttons[index].scrollRectToVisible(
new Rectangle(0,0, size.width,size.height));
}
});
}
}


13.1.3 JViewport属性

 

13.1.4 JViewport事件

 

例13-4 对JViewport变化事件的响应


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JViewport viewport = new JViewport();
JPanel view = new JPanel();

view.add(new JLabel(
new ImageIcon("anjinAndMariko.gif")));

viewport.setView(view);

contentPane.add(new ControlPanel(viewport),
BorderLayout.NORTH);
contentPane.add(viewport, BorderLayout.CENTER);
contentPane.add(new StatusPanel(viewport),
BorderLayout.SOUTH);
}
}
class StatusPanel extends JPanel {
private JLabel extentLabel = new JLabel(),
viewPositionLabel = new JLabel(),
viewSizeLabel = new JLabel();
private JViewport viewport;

public StatusPanel(JViewport vp) {
viewport = vp;

setBorder(BorderFactory.createEtchedBorder());
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

extentLabel.setAlignmentX(0.5f);
viewPositionLabel.setAlignmentX(0.5f);
viewSizeLabel.setAlignmentX(0.5f);

add(extentLabel);
add(viewPositionLabel);
add(viewSizeLabel);

viewport.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
Dimension extent = viewport.getExtentSize();
Point viewPosition = viewport.getViewPosition();
Rectangle viewSize = viewport.getViewRect();

extentLabel.setText("View Extent: " +
extent.toString());
viewPositionLabel.setText("View Position: " +
viewPosition.toString());
viewSizeLabel.setText("View Size: " +
viewSize.toString());
revalidate();
}
});
}
}
class ControlPanel extends JPanel {
private JViewport viewport;

private JButton[] buttons = {
new JButton("up"), new JButton("down"),
new JButton("left"), new JButton("right"),
};

public ControlPanel(JViewport vp) {
viewport = vp;

for(int i=0; i < buttons.length; ++i) {
add(buttons[i]);

buttons[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
scroll(e.getActionCommand());
}
});
}
}
private void scroll(String actionCmd) {
Point vp = viewport.getViewPosition();

if(actionCmd.equals("up")) vp.y += 5;
else if(actionCmd.equals("down")) vp.y -= 5;
else if(actionCmd.equals("left")) vp.x += 5;
else if(actionCmd.equals("right")) vp.x -= 5;

viewport.setViewPosition(vp);
}
}


13.1.5 JViewport类总结

 

13.1.6 AWT兼容

 

例13-5 使用JScrollPane


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JLabel view = new JLabel(new ImageIcon("cutlery.jpg",
"A picture of cutlery"));
JScrollPane sp = new JScrollPane(view);

contentPane.add(sp);
}
}


13.2 JScrollPane

 

13.2.1 滚动窗格的头部

 

例13-6 为滚动窗格的头部指定视图


import java.awt.*;
import javax.swing.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JLabel columnHeaderView = new JLabel(
new ImageIcon("horizontalRuler.jpg",
"horizontal ruler"));
JLabel rowHeaderView = new JLabel(
new ImageIcon("verticalRuler.jpg",
"vertical ruler"));
JLabel view = new JLabel(
new ImageIcon("grapes.jpg",
"grapes"));

JScrollPane sp = new JScrollPane(view);

sp.setColumnHeaderView(columnHeaderView);
sp.setRowHeaderView(rowHeaderView);

sp.setViewportBorder(
BorderFactory.createRaisedBevelBorder());

contentPane.add(sp);
}
}


例13-7 设置头部视口


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public void init() {
Container contentPane = getContentPane();
JViewport columnHeaderViewport = new JViewport();
JViewport rowHeaderViewport = new JViewport();

JLabel columnHeaderView = new JLabel(
new ImageIcon("horizontalRuler.jpg"));
JLabel rowHeaderView = new JLabel(
new ImageIcon("verticalRuler.jpg"));
JLabel view = new JLabel(
new ImageIcon("strawberry.jpg"));

JScrollPane sp = new JScrollPane(view);

sp.setToolTipText(
"Drag the headers to drag the picture!");

HeaderViewDragListener verticalHeaderListener =
new HeaderViewDragListener(sp,
SwingConstants.VERTICAL);

HeaderViewDragListener horizontalHeaderListener =
new HeaderViewDragListener(sp,
SwingConstants.HORIZONTAL);

columnHeaderViewport.addMouseListener(
horizontalHeaderListener);
columnHeaderViewport.addMouseMotionListener(
horizontalHeaderListener);

rowHeaderViewport.addMouseListener(
verticalHeaderListener);
rowHeaderViewport.addMouseMotionListener(
verticalHeaderListener);

// headers must be set before header views
sp.setColumnHeader(columnHeaderViewport);
sp.setRowHeader(rowHeaderViewport);

sp.setColumnHeaderView(columnHeaderView);
sp.setRowHeaderView(rowHeaderView);

contentPane.add(sp);
}
}
class HeaderViewDragListener extends MouseAdapter
implements MouseMotionListener,
SwingConstants {
private Point last = new Point();
private JScrollPane scrollpane;
private int orientation;

public HeaderViewDragListener(JScrollPane sp, int orient) {
scrollpane = sp;
orientation = orient;
}
public void mousePressed(MouseEvent e) {
last.x = e.getPoint().x;
last.y = e.getPoint().y;
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
JViewport headerViewport = (JViewport)e.getSource();
JViewport scrollpaneViewport = scrollpane.getViewport();
Dimension viewSize = scrollpaneViewport.getViewSize(),
extent = scrollpaneViewport.getExtentSize();

Point drag = e.getPoint();
Point offset = new Point(drag.x-last.x, drag.y-last.y);
Point headerPosition = new Point(), viewportPosition;

viewportPosition = scrollpaneViewport.getViewPosition();

if(orientation == HORIZONTAL) {
int nextX = viewportPosition.x - offset.x;
int rightEdge = extent.width + nextX;

if(nextX > 0 && rightEdge < viewSize.width) {
headerPosition.x = nextX;
viewportPosition.x = nextX;
}
}
if(orientation == VERTICAL) {
int nextY = viewportPosition.y - offset.y;
int bottomEdge = extent.height + nextY;

if(nextY > 0 && bottomEdge < viewSize.height) {
headerPosition.y = nextY;
viewportPosition.y = nextY;
}
}
headerViewport.setViewPosition(headerPosition);
scrollpaneViewport.setViewPosition(viewportPosition);

last.x = drag.x;
last.y = drag.y;
}
}


 

13.2.2 滚动窗的角部

 

例13-8 指定滚动窗格的角部的组件


import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JLabel columnHeaderView = new JLabel(
new ImageIcon("horizontalRuler.jpg"));
JLabel rowHeaderView = new JLabel(
new ImageIcon("verticalRuler.jpg"));
JLabel view = new JLabel(
new ImageIcon("anjinAndMariko.gif"));

JScrollPane sp = new JScrollPane(view);

JPanel corners[] = {
new JPanel(), new JPanel(),
new JPanel(), new JPanel()
};
String cornerConstants[] = {
ScrollPaneConstants.UPPER_LEFT_CORNER,
ScrollPaneConstants.LOWER_LEFT_CORNER,
ScrollPaneConstants.UPPER_RIGHT_CORNER,
ScrollPaneConstants.LOWER_RIGHT_CORNER,
};
Border border = BorderFactory.createEtchedBorder();

for(int i=0; i < corners.length; ++i) {
corners[i].setBorder(border);
sp.setCorner(cornerConstants[i], corners[i]);
}

sp.setColumnHeaderView(columnHeaderView);
sp.setRowHeaderView(rowHeaderView);
contentPane.add(sp);
}
}


13.2.3 JViewport属性

 

13.2.4 JViewport事件

 

13.2.5 JViewport类总结

 

例13-9 透明和不透明滚动窗格


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public void init() {
Container contentPane = new CustomContentPane();
JLabel view1 = new JLabel(
new ImageIcon("gjMedium.gif"));
JLabel view2 = new JLabel(
new ImageIcon("anjinAndMariko.gif"));

JScrollPane sp1 = new JScrollPane(view1);
JScrollPane sp2 = new JScrollPane(view2);

setContentPane(contentPane);
sp1.setPreferredSize(new Dimension(250,250));
sp2.setPreferredSize(new Dimension(250,250));

contentPane.add(sp1);
contentPane.add(sp2);
}
}
class CustomContentPane extends JPanel {
private ImageIcon rain = new ImageIcon("rain.gif");

public CustomContentPane() {
setLayout(new FlowLayout());
}
public void paintComponent(Graphics g) {
int rainw = rain.getIconWidth();
int rainh = rain.getIconHeight();

Dimension size = getSize();

for(int row=0; row < size.height; row += rainh)
for(int col=0; col < size.width; col += rainw)
rain.paintIcon(this,g,col,row);
}
}


13.2.6 AWT兼容

 

13.3 Scrollable接口

 

例13-10 跟踪视口宽度


import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class Test extends JApplet {
private JTextArea textArea = new JTextArea();

public void init() {
Container contentPane = getContentPane();

readFile();

contentPane.add(new ControlPanel(), BorderLayout.NORTH);
contentPane.add(new JScrollPane(textArea),
BorderLayout.CENTER);
}
private void readFile() {
DefaultEditorKit kit = new DefaultEditorKit();

try {
kit.read(new FileReader("Test.java"),
textArea.getDocument(), 0);
}
catch(Exception ex) { ex.printStackTrace(); }
}
class ControlPanel extends JPanel {
public ControlPanel() {
final JCheckBox cb = new JCheckBox("wrap");

add(cb);

cb.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if(cb.isSelected())
textArea.setLineWrap(true);
else
textArea.setLineWrap(false);
}
});
}
}
}


13.4 JScrollBar

 

 

13.4.1 使用Swing的JScrollBar类进行手动滚动

 

13.4.2 块增量和单元增量

 

13.4.3 JScrollBar属性

 

例13-11 为JScrollBar的实例指定单增量和块增量


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Test extends JApplet {
private JScrollBar vsb = new JScrollBar(JScrollBar.VERTICAL);
private SSPanel panel = new SSPanel();

public Test() {
Container contentPane = getContentPane();

contentPane.add(panel, BorderLayout.CENTER);
contentPane.add(vsb, BorderLayout.EAST);

vsb.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(
AdjustmentEvent e) {
JScrollBar sb = (JScrollBar)e.getSource();
showScrollBarValues();
panel.setTopIndexByPixelValue(e.getValue());
panel.repaint();
}
});
}
public void paint(Graphics g) {
Dimension pref = panel.getPreferredSize();
Dimension size = panel.getSize();
int extent = size.height, max = pref.height;
int value = Math.max(0,
Math.min(vsb.getValue(), max - extent));

vsb.setVisible(extent < max);
vsb.setUnitIncrement(panel.getUnitHeight());
vsb.setBlockIncrement(extent - vsb.getUnitIncrement());
vsb.setValues(value, extent, 0, max);

showScrollBarValues();
super.paint(g);
}
private void showScrollBarValues() {
showStatus("min: " + vsb.getMinimum() +
", max: " + vsb.getMaximum() +
", visible amount: " +
vsb.getVisibleAmount() +
", value: " + vsb.getValue());
}
}
class SSPanel extends JPanel {
private int topIndex = 0;
private int fh;

private String[] data = {
"Brown, Ted: 000-00-0001", "Brown, Ted: 000-00-0002",
"Brown, Ted: 000-00-0003", "Brown, Ted: 000-00-0004",
"Brown, Ted: 000-00-0005", "Brown, Ted: 000-00-0006",
"Brown, Ted: 000-00-0007", "Brown, Ted: 000-00-0008",
"Brown, Ted: 000-00-0009", "Brown, Ted: 000-00-00010",
"Brown, Ted: 000-00-00011", "Brown, Ted: 000-00-00012",
"Brown, Ted: 000-00-00013", "Brown, Ted: 000-00-00014",
"Brown, Ted: 000-00-00015", "Brown, Ted: 000-00-00016",
"Brown, Ted: 000-00-00017", "Brown, Ted: 000-00-00018",
"Brown, Ted: 000-00-00019", "Brown, Ted: 000-00-00020",
"Brown, Ted: 000-00-00021", "Brown, Ted: 000-00-00022",
"Brown, Ted: 000-00-00023", "Brown, Ted: 000-00-00024",
"Brown, Ted: 000-00-00025", "Brown, Ted: 000-00-00026",
"Brown, Ted: 000-00-00027", "Brown, Ted: 000-00-00028",
"Brown, Ted: 000-00-00029", "Brown, Ted: 000-00-00030",
};
public void paintComponent(Graphics g) {
Color color = g.getColor();
super.paintComponent(g);
g.setColor(color);

Dimension size = getSize();
Insets insets = getInsets();
int y = insets.top;

for(int i = topIndex; i < data.length; ++i, y += fh) {
g.drawString(data[i], 0, y);

if(y + fh > size.height - insets.bottom)
break;
}
}
public void setTopIndexByPixelValue(int pixelValue) {
topIndex = pixelValue / fh;
}
public int getUnitHeight() {
return fh;
}
public Dimension getPreferredSize() {
Dimension dim = new Dimension();
Graphics g = getGraphics();

try {
FontMetrics fm = g.getFontMetrics();
fh = fm.getHeight();

dim.width = fm.stringWidth(data[data.length-1]);
dim.height = fm.getHeight() * (data.length + 1);
}
finally {
g.dispose();
}
return dim;
}
}


13.4.4 JScrollBar事件

 

例13-12 使用JScrollBar的valueIsAdjusting属性


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Test extends JApplet {
public Test() {
Container contentPane = getContentPane();
JScrollBar sb = new JScrollBar();

contentPane.add(sb, BorderLayout.EAST);

sb.addAdjustmentListener(new AdjustmentListener() {
public void adjustmentValueChanged(
AdjustmentEvent e) {
JScrollBar jsb = (JScrollBar)e.getAdjustable();

if(jsb.getValueIsAdjusting())
showStatus("adjusting ...");
else
showStatus(Integer.toString(e.getValue()));
}
});
}
}

阅读(1656) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2008-06-19 14:43:39

论翻译公司间谍案与中西方文化差异 据美国《华盛顿时报》网站12月21日报道,美国情报官员说,中国方面曾通过一个中文翻译服务机构以获得美国国家安全局设在夏威夷的一个监听站的情报。这个间谍渗透案是在几年前海军部犯罪调查局进行的一次重大反情报调查中发现的。这次反情报调查揭露了中国方面窃取密码和其它电子情报机密,以及招募有关军事和文职人员的一个大型项目。 官员说,中国方面通过在夏威夷设立一家中文[URL=http://www.jiayinte.com]翻译公司[/URL]来执行间谍行动。中方将这家公司伪装成一家来自美国的企业。这一计策使海军和国家安全局同该公司签订了机密合同。根据合同,该公司帮助[URL=http://www.jiayinte.com]翻译[/URL]国家安全局所截获的情报中的一些信息。 海军部犯罪调查局还发现了一个重大的中国情报行动。该行动的目的是招募美国华裔担任间谍,并招募可以获得那家情报站机密情报的海军和文职情报工作人员。我们可以看到,美国的情报人员在中国威胁论这样接近于变态的指导思想下去勾画出这样一个故事并不是为了制造新闻赚个噱头,而是别有用心的想从各个方面证明中国