我有一个自定义JPanel
类,我希望它在它的子组件前面绘制几个矩形和文本。我已经覆盖了这个方法:
public void paint(Graphics g){
g = getComponentGraphics(g);
super.paint(g);
//paint my custom content
}
super.paint
调用paintChildren
whitch绘制子组件。但是子组件出现在我的自定义内容之前,他们有时也会互相争斗。
我完全不知道可能导致这种情况的原因。
注意:我在代码中使用setComponentZOrder
,而我的JPanel
则在JScrollPane
中使用。
编辑:组件ZFight即使我从不调用setComponentZOrder方法。
编辑2:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleSelection;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JPanel{
private static final long serialVersionUID = 1L;
public static void main(String[] atgs){
JFrame frame = new JFrame("ZFightingExample");
frame.setSize(new Dimension(500,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ExamplePanel panel = new ExamplePanel();
frame.add(panel);
Example a = new Example(new Rectangle(5,5,50,50)),
b = new Example(new Rectangle(40,40,50,50));
panel.add(a);
panel.add(b);
frame.setVisible(true);
}
public Example(Rectangle bounds){
super();
setBounds(bounds);
}
public void paint(Graphics g){
super.setBackground(Color.GREEN);
g.fillRect(0, 0, getWidth()-1, getHeight()-1);
super.paint(g);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
}
class ExamplePanel extends JPanel{
private static final long serialVersionUID = 1L;
public ExamplePanel(){
super(null);
accessibleContext = new Accessiblecontext();
};
protected class Accessiblecontext extends AccessibleJPanel implements AccessibleSelection{
private static final long serialVersionUID = 1L;
public int getAccessibleSelectionCount() {return 2;}
public Accessible getAccessibleSelection(int i) {return (Accessible)getComponent(i);}
public boolean isAccessibleChildSelected(int i) {return true;}
public void addAccessibleSelection(int i) {}
public void removeAccessibleSelection(int i) {}
public void clearAccessibleSelection() {}
public void selectAllAccessibleSelection() {}
}
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLUE);//Should be in front of the Green boxes...
g.drawRect(10, 10, 75, 75);
}
}
答案 0 :(得分:2)
我希望它在它的子组件前面绘制几个矩形和文本。
通常你会覆盖paintCompnent()来进行自定义绘画。
问题是"在前面"对你意味着什么?如果它意味着我的意思,那么你需要在绘制子组件后进行绘画。所以你覆盖paint()的基本方法是正确的。
public void paint(Graphics g){
g = getComponentGraphics(g);
super.paint(g);
//paint my custom content
}
上述代码的问题在于您没有使用传递给绘制方法的Graphics对象。所以你的代码应该是:
public void paint(Graphics g)
{
//g = getComponentGraphics(g);
super.paint(g); // use the Graphics object passed to the method
//paint my custom content
g.drawRect(10, 10, 20, 20);
}
我在我的代码中使用了setComponentZOrder,
你为什么玩ZOrder?
修改强>
g.setColor(Color.BLUE); //应位于绿色框前面......
正如我在回答中首次提到的,通常(99%的时间)自定义绘制是通过覆盖面板的paintComponent()方法完成的。
问题在于Example类:
因此代码可能类似于:
public Example(Rectangle bounds){
super();
setBounds(bounds);
setBackground(Color.GREEN);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth()-1, getHeight()-1);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
请注意,您不需要使用Example类进行任何自定义绘制。相反,您的代码可能是:
ExamplePanel panel = new ExamplePanel();
panel.setLayout( null ); // now you set the size/location of any component you add to the panel
JPanel example1 = new JPanel();
example1.setBackground( Color.GREEN );
example1.setBorder( new LineBorder(Color.BLACK) );
example1.setBounds( new Rectangle(....) );
panel.add(example1);
此外,ExamplePanel类的另一个解决方案可能是使用JLayer。 JLayer类允许您向组件添加各种奇特的装饰。查看How to Decorate Components With The JLayer Class上的Swing教程。