2016-08-20 6 views
1

Ich habe eine benutzerdefinierte JPanel Klasse und ich will es mehrere Rechtecke und Texte vor seiner Kind-Komponenten zu malen. Ich habe diese Methode außer Kraft gesetzt:Komponenten rendern eine ungewöhnliche Weise

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

super.paint Anrufe paintChildren whitch die untergeordneten Komponenten zieht. Aber die Kind-Komponenten erscheinen vor meinen eigenen Inhalten, und manchmal streiten sie auch miteinander.

Ich bin absolut ahnungslos über das, was dies verursachen könnte.

HINWEIS: Ich verwende setComponentZOrder in meinem Code, und meine JPanel findet in einem JScrollPane statt.

EDIT: Die Komponenten ZFight auch wenn ich nie die SetComponentZOrder-Methode aufrufen.

EDIT 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) Für bessere Hilfe, früher, ein [MCVE] oder [kurze, selbständige, korrekte Beispiel] (http://www.sscce.org/). 2) scheint, dass Sie mehr Glück mit einem 'JLayeredPane' haben können, aber das ist nur eine Vermutung. Posten Sie einen MCVE und eine detaillierte Beschreibung dessen, was passieren soll. –

+2

3) Sogar von * "Ich habe eine benutzerdefinierte' JPanel' .. 'öffentliche void Farbe (Graphics g) {' "* Es ist offensichtlich, dass Sie in der falschen Richtung über benutzerdefinierte Malerei gehen. –

+2

"Swing-Programme sollten' paintComponent() 'überschreiben, anstatt' paint() '' zu überschreiben. "- [* Painting in AWT and Swing: Die Malmethoden *] (http://www.oracle.com/technetwork/java/ painting-140037.html # Rückrufe). – trashgod

Antwort

2

ich möchte es mehrere Rechtecke und Texte vor, es ist Kind Komponenten zu malen.

Normalerweise überschreiben Sie paintCompnent(), um benutzerdefinierte Bilder zu erstellen.

Die Frage ist, was bedeutet "vorne" für Sie? Wenn es bedeutet, was es meiner Meinung nach bedeutet, dann müssen Sie nach dem Malen der Kinderkomponenten malen. Also ist der grundlegende Ansatz zum Überschreiben von paint() korrekt.

Das Problem mit dem obigen Code besteht darin, dass Sie nicht das Grafikobjekt verwenden, das an die Malmethode übergeben wird. So sollte Ihr Code sein:

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

Ich benutze setComponentZOrder in meinem Code,

Warum spielst du mit ZOrder?

Edit:

g.setColor (Color.BLUE); // vor der Grün-Box sein sollte ...

Als ich zum ersten Mal in meiner Antwort erwähnt, Normalerweise (99% der Zeit) erfolgt das benutzerdefinierte Malen durch Überschreiben der paintComponent() -Methode des Panels.

Das Problem ist mit der Beispielklasse:

  1. override paintcomponent() nicht malen()
  2. die erste Anweisung, wenn Sie eine Malerei-Methode überschreiben sollten Super sein ???..
  3. nicht Eigenschaften der Klasse in der Malmethode festlegen.

So könnte der Code in etwa so aussehen:

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

Hinweis Sie nicht Ereignis tun müssen, mit der Beispielklasse beliebige benutzerdefinierte Malerei zu tun. Stattdessen Ihr Code so etwas wie sein könnte:

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

Auch eine andere Lösung für die ExamplePanel Klasse könnte sein, eine JLayer zu verwenden. Mit der JLayer-Klasse können Sie einer Komponente alle Arten von ausgefallenen Dekorationen hinzufügen. Schau dir das Swing-Tutorial unter How to Decorate Components With The JLayer Class an.

+0

Ich baue eine Implementierung von 'AccessibleSelection' und die ausgewählten Komponenten werden nach vorne verschoben. "Vor" bedeutet, dass ich meinen Inhalt nach den Komponenten zeichnen lassen möchte. – Gergely

+0

Diese Lösung lässt meinen Inhalt nicht vor den Komponenten erscheinen. – Gergely

+0

@Gergely, ja es tut benutzerdefinierte Bilder (Rechtecke und Text zeichnen) über die Komponenten, die dem Panel hinzugefügt werden. Wenn Sie das nicht versuchen, verstehe ich die Frage nicht. Sie wurden gebeten, Ihnen einen einfachen Democode zu senden, damit wir besser verstehen, was Sie zu tun versuchen. Da können wir dir nicht helfen, es zu reparieren. – camickr