我有一个JPanel,其中填充了几个不透明的自定义组件。现在我想通过覆盖paintComponent()方法在这些组件之上绘制一些东西。我的问题是,涂漆的东西放在嵌入式组件的后面,因为它们是不透明的,所以被它们覆盖。
有没有办法让绘画出现在组件的顶部?
以下是我正在尝试做的一个简短示例:
public class DrawOnTop {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Draw on top");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
});
}
}
class MyPanel extends JPanel {
public MyPanel() {
setLayout(new BorderLayout(3, 3));
add(new JButton("Button 1"), BorderLayout.NORTH);
add(new JButton("Button 2"), BorderLayout.CENTER);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
}
}
答案 0 :(得分:2)
你正在思考正确的方向。
唯一的问题是你应该像下面的代码中那样重写paintChildren()
方法。这是因为首先调用paintComponent()
方法并对组件本身进行背景等绘制(MyPanel
),然后调用paintBorders()
,最后调用paintChildren()
绘制调用它的组件内部的所有内容。
public class DrawOnTop {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame("Draw on top");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
});
}
}
class MyPanel extends JPanel {
public MyPanel() {
setLayout(new BorderLayout(3, 3));
JButton b1 = new JButton("Button 1");
MouseListener ml = new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
super.mouseExited(e);
MyPanel.this.repaint();
}
};
b1.addMouseListener(ml);
JButton b2 = new JButton("Button 2");
b2.addMouseListener(ml);
add(b1, BorderLayout.NORTH);
add(b2, BorderLayout.CENTER);
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
g.setColor(Color.red);
g.drawLine(0, 0, getVisibleRect().width, getVisibleRect().height);
}
}
需要注意的重要事项,在代码示例中,当鼠标退出按钮时,我还添加了MouseListener
来重新绘制面板,否则按钮将始终保持在线上鼠标进入其中一个。
但是如果你想要一个总是在你的组件之上的自定义绘画,那么我建议使用一个玻璃窗格。 此处提供了使用玻璃窗格的示例: