2016-08-20 2 views
1

저는 사용자 정의 JPanel 클래스를 가지고 있으며, 아이 컴포넌트 앞에 여러 개의 직사각형과 텍스트를 칠하고 싶습니다. 하위 구성 요소를 그립니다 whitch구성 요소가 비정상적인 방식으로 렌더링됩니다.

public void paint(Graphics g){ 
    g = getComponentGraphics(g); 
    super.paint(g); 
    //paint my custom content 
} 

super.paint 전화 paintChildren :이 방법을 무시했다. 그러나 하위 구성 요소는 내 사용자 지정 콘텐츠 앞에 표시되며 때로는 Z가 서로 대결합니다.

저는이 문제의 원인에 대해 전혀 알지 못합니다.

참고 : setComponentZOrder을 내 코드에 사용하고 JPanelJScrollPane에서 발생합니다.

편집 : 구성 요소 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); 
     } 
    } 
+2

1) 더 나은 도움을 받으려면 [MCVE] 또는 [Short, Self Contained, Correct Example] (http://www.sscce.org/)를 게시하십시오. 2)'JLayeredPane'을 사용하면 더 나은 행운을 누릴 수 있습니다. 그러나 이것은 단지 추측에 불과합니다. MCVE 게시 및 일어날 일에 대한 자세한 설명. –

+2

3) * "나는 사용자 정의'JPanel'을 가지고있다.'public void paint (Graphics g) {'"* 사용자 정의 그림에 대해 잘못된 방향으로 가고있다. –

+2

"스윙 프로그램은'paint()'를 오버라이드하는 대신'paintComponent()'를 덮어 써야합니다."- [AWT와 스윙의 페인팅 : 페인트 방법 *] (http://www.oracle.com/technetwork/java/) painting-140037.html # callbacks). – trashgod

답변

2

나는 그것의 앞에 몇 가지 사각형과 텍스트를 페인트 할 하위 구성 요소입니다.

일반적으로 paintCompnent()를 재정 의하여 사용자 정의 페인팅을 수행합니다.

"앞에서"당신에게 무슨 의미입니까? 내 생각이 의미하는 바를 말하면 자식 구성 요소를 칠한 후에 그림을 그려야합니다. 따라서 페인트()를 재정의하는 기본 접근법이 정확합니다.

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); //이

내가 처음 내 대답에 명시된 바와 같이 ... 녹색 상자 앞에있을 경우, 일반적으로 사용자 정의 페인팅은 패널의 paintComponent() 메소드를 대체하여 수행됩니다.

문제는 예제 클래스입니다 :

  1. 재정의 paintComponent()는 페인트하지()
  2. 당신이 슈퍼해야한다 그림의 메소드를 오버라이드 (override) 첫 번째 문 ???..
  3. 그림 메서드에서 클래스의 속성을 설정하지 마십시오.그렇지 이벤트 수행 예 클래스와 사용자 정의 그림을 할 필요가

    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); 

또 다른 솔루션은 JLayer를 사용하는 것일 수 있습니다. JLayer 클래스를 사용하면 모든 종류의 고급 장식을 구성 요소에 추가 할 수 있습니다. How to Decorate Components With The JLayer Class에서 스윙 튜토리얼을 확인하십시오.

+0

'AccessibleSelection'의 구현물을 만들고 선택된 컴포넌트를 앞에 배치했습니다. "앞에"는 구성 요소 다음에 내 콘텐트를 그려야 함을 의미합니다. – Gergely

+0

이 솔루션은 컨텐츠를 구성 요소 앞에 표시하지 않습니다. – Gergely

+0

@Gergely, 예. 패널에 추가 된 구성 요소 위에 맞춤형 페인팅 (사각형 및 텍스트 그리기)을 수행합니다. 이것이 당신이하려고하는 것이 아니라면 나는 그 질문을 이해하지 못합니다. 귀하가하려는 일을 이해하는 데 도움이되는 간단한 데모 코드를 게시하도록 요청 받았습니다. 네가 가진 것이 아니기 때문에 우리가 너를 고칠 수는 없어. – camickr

관련 문제