Java 组件以一种不寻常的方式呈现

Java 组件以一种不寻常的方式呈现,java,swing,graphics,Java,Swing,Graphics,我有一个自定义的JPanel类,我希望它在子组件前面绘制几个矩形和文本。我已重写此方法: public void paint(Graphics g){ g = getComponentGraphics(g); super.paint(g); //paint my custom content } super.paint调用paintChildrenwhich绘制子组件。但是子组件出现在我的自定义内容前面,它们有时也会相互争斗 我完全不知道是什么导致了这一切 注意:我在代

我有一个自定义的
JPanel
类,我希望它在子组件前面绘制几个矩形和文本。我已重写此方法:

public void paint(Graphics g){
    g = getComponentGraphics(g);
    super.paint(g);
    //paint my custom content
}
super.paint
调用
paintChildren
which绘制子组件。但是子组件出现在我的自定义内容前面,它们有时也会相互争斗

我完全不知道是什么导致了这一切

注意:我在代码中使用
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);
        }
    }
我希望它在它的子组件前面画几个矩形和文本

通常,您可以重写paintcompent()来进行自定义绘制

问题是“在前面”对你意味着什么?如果它的意思是我认为它的意思,那么你需要在子组件被绘制之后进行绘制。所以您知道覆盖paint()的基本方法是正确的

public void paint(Graphics g){
    g = getComponentGraphics(g);
    super.paint(g);
    //paint my custom content
}
上面代码的问题是,您没有使用传递给绘画方法的图形对象。因此,您的代码应该是:

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

你为什么和佐德玩

编辑:

g、 setColor(Color.BLUE)//应该在绿色的盒子前面

正如我在回答中首先指出的,通常(99%的时间)自定义绘制是通过覆盖面板的paintComponent()方法完成的

问题在于示例类:

  • 覆盖paintComponent()而不是paint()
  • 重写绘制方法时的第一条语句应该是super
  • 不要在绘制方法中设置类的属性
  • 因此,代码可能类似于:

    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);
    }
    
    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);
    
    注意,您不需要使用示例类进行任何自定义绘制。相反,您的代码可能类似于:

    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);
    }
    
    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类允许您向组件添加各种花式装饰。查看上的Swing教程。

    1)要更快获得更好的帮助,请发布或。2) 似乎您使用
    JLayeredPane
    可能会更幸运,但这只是一个猜测。发布一个MCVE&一个应该发生什么的详细描述。3)即使是从“我有一个自定义
    JPanel
    public void paint(Graphics g){
    ”开始,显然你在自定义绘制方面走错了路。“Swing程序应该重写
    paintComponent()
    ,而不是重写
    paint()
    ”-.现在我正在为这个做一个SSCCE…但它就是不起作用out@Gergely,
    ,但它只是不起作用
    -如果代码起作用,那么就不需要问问题。SSCCE的目的是发布简单的代码来演示你在做什么。然后也许我们可以帮助指出你做错了什么。我正在构建一个impleme
    AccessibleSelection
    的显示和所选组件移到前面。“前面”表示我希望在组件之后绘制内容。此解决方案不会使我的内容显示在组件前面。@Gergely,是的,它会进行自定义绘制(绘制矩形和文本)在添加到面板的组件之上。如果这不是您试图做的,那么我不理解这个问题。您被要求发布简单的演示代码,以帮助我们理解您试图做的事情。因为您没有,我们无法帮助您解决它。@Gergely,这就是为什么我们需要一个SSCCE来解决每个问题。我们无法解决我猜您正在两个组件上进行自定义绘制。我们始终需要SSCCE来准确查看您正在执行的操作。请参见编辑。