Java教程是针对JDK 8编写的。本页面中描述的示例和实践未利用后续版本引入的改进,并可能使用不再可用的技术。
有关Java SE 9及后续版本中更新的语言特性的摘要,请参阅Java语言变更。
有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息,请参阅JDK发行说明。
问题1. JComponent 定义的哪个方法绘制组件的内部内容?
答案1: paintComponent 方法绘制组件的内部内容(不包括任何子组件)。
问题2. 下面哪个代码片段绘制一个大小为 100x100 像素的矩形(填充或非填充)?
a. g.fillRect(x, y, 100, 100)
b. g.fillRect(x, y, 99, 99)
c. g.drawRect(x, y, 100, 100)
d. b 和 c
e. a 和 c
答案2: a. drawRect 方法在指定矩形的下方绘制线条。因此,要得到一个大小为 100x100 的矩形,需要将 drawRect 的宽度和高度指定为 99, 99。而对于 fillXxx 方法,你需要精确指定所需的宽度和高度,所以 g.fillRect(x, y, 100, 100) 会得到一个大小为 100x100 的矩形。
问题3. 如何使用背景颜色的50%透明度来让一个组件执行下一个绘制操作?
答案3:
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
练习1. 使用标准边框和自定义组件绘制,实现一个组件,它的首选大小为 250x100,默认情况下是不透明的,有一个5像素宽的黑色边框,并使用前景色绘制一个“X”(使用5像素粗的线),如下图所示:
答案1: 参见 XMarksTheSpot.java,你可以使用 ComponentDisplayer.java 运行它。
以下代码设置了 XMarksTheSpot 组件的边框:
setBorder(BorderFactory.createMatteBorder(5,5,5,5, Color.BLACK));
以下是来自 XMarksTheSpot 的 paintComponent 方法中的绘制“X”的代码:
Graphics2D g2 = (Graphics2D)g;
Insets insets = getInsets();
g2.setStroke(new BasicStroke(5.0f));
g2.draw(new Line2D.Double(insets.left,
insets.top,
getWidth() - insets.right,
getHeight() - insets.bottom));
g2.draw(new Line2D.Double(insets.left,
getHeight() - insets.bottom,
getWidth() - insets.right,
insets.top));
练习2. 实现一个尺寸为 10x10 像素的图标,绘制填充整个 10x10 区域的实心矩形。如果图标的组件是启用的,则矩形应为红色;如果禁用,则为灰色。复制 ButtonDemo.java,使用你自定义的 Icon 替代中间按钮中显示的 middle.gif。下面的图片展示了图标的外观。
答案2: 请查看SquareIcon.java,您可以使用这个修改后的ButtonDemo.java运行。
以下是设置图标的代码:
Icon middleButtonIcon = new SquareIcon();
...
b2 = new JButton("中间按钮", middleButtonIcon);
这是SquareIcon实现Icon接口所需的三个方法:
public void paintIcon(Component c, Graphics g,
int x, int y) {
if (c.isEnabled()) {
g.setColor(Color.RED);
} else {
g.setColor(Color.GRAY);
}
g.fillRect(x, y, SIZE, SIZE);
}
public int getIconWidth() {
return SIZE;
}
public int getIconHeight() {
return SIZE;
}
练习3. 实现一个边框,将一个红色的15像素高的条纹画在组件的顶部。通过用这个边框替换练习1中创建的组件的边框来测试。结果应该如下图所示。
答案3: 请查看StripeBorder.java,您可以使用ComponentDisplayer.java和XMarksTheSpot.java运行(请确保取消注释设置边框为StripeBorder的那一行)。这是StripeBorder实现Border接口所需的三个方法:
public void paintBorder(Component c, Graphics g,
int x, int y,
int width, int height) {
g.setColor(Color.RED);
g.fillRect(x, y, c.getWidth(), HEIGHT);
}
public Insets getBorderInsets(Component c) {
return new Insets(HEIGHT, 0, 0, 0);
}
public boolean isBorderOpaque() {
return true;
}