java – 存在JMenu时JPanel#paintChildren(Graphics)的错误行为?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 存在JMenu时JPanel#paintChildren(Graphics)的错误行为?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3393字,纯文字阅读大概需要5分钟。
内容图文
![java – 存在JMenu时JPanel#paintChildren(Graphics)的错误行为?](/upload/InfoBanner/zyjiaocheng/803/c0e353d90c1b4d459852efde3f70cffe.jpg)
我想做的事:
创建一个JPanel的子类,在包含的组件之上绘制一个简单的叠加层.
为什么我不使用JLayeredPane?
请参见JComponent#isOptimizedDrawingEnabled().
当JMenu存在于JFrame中时,添加带有重写的paintChildren(Graphics)方法的JPanel,在传递的Graphics对象中提供了一个不正确的坐标起点,如此代码示例所示:
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
public final class Sscce {
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
// a normal frame
JFrame f = new JFrame();
// set up a simple menu
JMenuBar mb = new JMenuBar();
JMenu m = new JMenu("Test");
JMenuItem mi = new JMenu("Whatever");
m.add(mi);
mb.add(m);
f.setJMenuBar(mb);
// a panel with a simple text overlay over components.
// works much faster than JLayeredPane, which doesn't have
// isOptimizedDrawingEnabled()
JPanel p = new JPanel() {
@Override
public void paint(Graphics g) {
// I'm not so stupid to draw stuff here
super.paint(g);
// JavaDoc: delegates to paintComponent, paintBorder, paintChildren
// in that order
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// it is common knowledge that children are painted after parent
Graphics tmp = g.create();
try {
tmp.setColor(Color.MAGENTA);
tmp.fillRect(0, 0, getWidth(), getHeight());
} finally {
tmp.dispose();
}
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
// draw some text
FontMetrics fm = g.getFontMetrics();
// will be drawn outside panel; under menu
g.drawString("TEST TOP/LEFT", 0 + getX(), 0 + getY());
final String s = "TEST BOTTOM/RIGHT";
// will be drawn noticeably above the bottom
g.drawString(s,
getWidth() - fm.charsWidth(s.toCharArray(), 0, s.length()),
getHeight() - fm.getHeight());
}
};
// add something to the panel
p.add(new JTextArea(10, 15));
f.add(p);
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
} catch (Throwable t) {
// this is a SSCCE
}
}
}
第一个字符串是在JPanel外部(在JMenu下)绘制的,即使两个坐标都是非负的.
第二个字符串未在右下角绘制.它被JMenu的高度推高了.
即使:
当AWT调用此方法时,Graphics对象参数已预先配置为在此特定组件上绘制的适当状态:
> Graphics对象的颜色设置为组件的前景
属性.
> Graphics对象的字体设置为组件的字体
属性.
>图形对象的翻译设置为
coordinate(0,0)表示组件的左上角.
> Graphics对象的剪辑矩形设置为的区域
需要重新涂漆的组件.
程序必须使用此Graphics对象(或从其派生的对象)来呈现输出.他们可以根据需要随意更改Graphics对象的状态.
我究竟做错了什么?
解决方法:
The first string is drawn outside of
JPanel
(under theJMenu
), even though both coordinates are non-negative. The second string is NOT drawn at the bottom right corner. It is pushed up by the height of theJMenu
.
在这两种情况下,请注意drawString()要求坐标表示字符串的baseline.在这种情况下,字体的上升和下降很有用. mb.getHeight()和fm.getHeight()具有可比性,可能是巧合.
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
// draw some text
FontMetrics fm = g.getFontMetrics();
// will be drawn outside panel; under menu
g.drawString("TEST TOP/LEFT", 0, fm.getAscent());
final String s = "TEST BOTTOM/RIGHT";
// will be drawn noticeably above the bottom
g.drawString(s, getWidth() - fm.stringWidth(s),
getHeight() - fm.getDescent());
}
内容总结
以上是互联网集市为您收集整理的java – 存在JMenu时JPanel#paintChildren(Graphics)的错误行为?全部内容,希望文章能够帮你解决java – 存在JMenu时JPanel#paintChildren(Graphics)的错误行为?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。