This discussion is archived
8 Replies Latest reply: Feb 7, 2012 11:45 AM by morgalr RSS

Painting Over JTextField

844235 Newbie
Currently Being Moderated
Hi everyone,

I tried to do the following :
-> I implemented a class Class1 derived from JPanel.
-----> Each object created from Class1 is a square and each side is made up of 59 pixels.
------> Each object created from Class1 contains a JTextField object named tf1.
----------> Here are the bounds of tf1 : x=0 ; y=0 ; width=59px ; height=59px

-----> I redefined the paint method :
----------> I drew a line (let's call it line1) starting from the point (x=30 ; y=0) and ending to the point (x=30 ; y=58).

-> In a test class :
-----> I made an instance of Class1 and I displayed it inside a window but line1 is drawn behind tf1.
---------> My question is : How can I paint geometries above tf1 by redefining the paint method in Class1 ?

Thanks in adance for your future help

Edited by: 841232 on 29 nov. 2011 23:56
  • 1. Re: Painting Over JTextField
    StanislavL Pro
    Currently Being Moderated
    Try to override the Class1's
    protected void paintChildren(Graphics g) {
      super.paintChildren(g);
      customPaintMethod(g);
    }
  • 2. Re: Painting Over JTextField
    844235 Newbie
    Currently Being Moderated
    I thank you for your answer.
    It leads me to a way close to the solution.
    I redefined the Class1's paint method as follows :
    public void paint(Graphics g) {
              
         super.paintChildren(g);
         this.paintComponent(g);
         super.paintBorder(g);
    }
    I also redefined the Class1's paintComponent method.
    I wrote inside all code to draw Line1.

    But :
    I made a test.
    I instanciated an occurence occur1 from Class1 and I displayed it inside a window.
    The first time occur1 is displayed Line1 is not visible as it is drawn behind tf1.
    Line1 is visible and drawn above tf1 as soon as I resized the window.
    It seems that the paint method redefinition is not considered at the first display.
    Does someone know a reason to explain this fact ?

    Thank you in advance for your future help
  • 3. Re: Painting Over JTextField
    StanislavL Pro
    Currently Being Moderated
    Please post SSCCE to say more.
  • 4. Re: Painting Over JTextField
    844235 Newbie
    Currently Being Moderated
    Ok, I will try to describe my example clearer in this post.

    Here is Class1's Java code :
    public class Class1 extends JPanel {
    
         private JTextField _tf1;
         
         public Class1() {
              StrokeBorder strokeBorder;
              BasicStroke basicStroke;
              
              this.setLayout(null);
              this.setSize(59, 59);
              
              basicStroke = new BasicStroke(1);
              strokeBorder = new StrokeBorder(basicStroke);
              this.setBorder(strokeBorder);
              
              _tf1 = new JTextField("T");
              _tf1.setEditable(false);
              this.add(_tf1);
              _tf1.setBounds(1, 1, 57, 57);
         }
         
         /**
          * Redefinition of the paint method to change the call order to
          * paintComponent, paintBorder and paintChildren
          * 
          * paintComponent is the last method called so a vertical line
          * is supposed to be drawn above the JTextField.
          */
         public void paint(Graphics g) {
              
              this.paintBorder(g);
              this.paintChildren(g); //< Paints the JTextField.
              this.paintComponent(g); //< Paints a vertical line.
         }
         
         /**
          * Redefinition of the paintComponent method to draw a vertical line.
          */
         protected void paintComponent(Graphics g) {
              g.drawLine(29, 0, 29, 58);
         }
    }
    Here is my main class's Java code :
    public class Main {
    
         public static void main(String[] args) {
              JFrame frame;
              Class1 class1;
              
              frame = new JFrame();
              frame.setSize(400, 400);
              frame.setLayout(null);
              frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
              
              class1 = new Class1();
              frame.add(class1);
              class1.setLocation(300, 300);
              
              frame.setVisible(true);
         }
    }
    When I run my program a window is displayed on the screen.
    A square JPanel - class1 - is located inside the window.
    Here is a screen capture when the window is freshly displayed : [http://img803.imageshack.us/img803/2011/firstdisplay.png]
    The screen capture shows a bug.
    A vertical line is supposed to be drawn above _tf1 in class1.

    Here is a screen capture when I have just resized the window : [http://img191.imageshack.us/img191/929/afterresizing.png]
    Now the vertical line is drawn as expected.

    I hope my example is clear now and you will be able to help me.
    Thenks in advance for your future help.
  • 5. Re: Painting Over JTextField
    Maxideon Explorer
    Currently Being Moderated
    A child component needs to be set nonopaque for the paint calls to always be forwarded to the parent. So include
     
    _tf1.setOpaque(false); 
    This isn't the complete solution though. The textfield will no longer paint its background, in effect leaving what's already there during repaints. So you need the parent, then, to paint the background. To do this, delete the overridden paint() method, delete the overridden paintComponent(), and override the paintChildren() method instead,
     
    @Override 
    public void paintChildren(Graphics g) { 
        super.paintChildren(g); 
        g.drawLine(29, 0, 29, 58); 
    } 
    as was suggested.
  • 6. Re: Painting Over JTextField
    844235 Newbie
    Currently Being Moderated
    I thank you for your answer.

    I applied your advices.
    Now, the vertical line is visible at first display.

    I modified my SSCCE example to make it closer to my project.
    Now I display the Class1's object inside an Applet.
    But I am facing a new difficulty.
    The border of my Class1 object disappears as soon as the Applet viewer is resized.
    I made a test in an Internet browser and the problem happened as well.
    Here are two screenshots to have a better idea of the problem :
    -> The applet viewer at first display : [http://img577.imageshack.us/img577/2011/firstdisplay.png]
    -> The applet viewer after manual resizing : [http://img16.imageshack.us/img16/929/afterresizing.png]

    Here is my applet's source code :
    public class MyApplet extends Applet {
         
         public void init() {
              
              Class1 class1;
              
              this.setLayout(null);
              this.setSize(400, 400);
              
              class1 = new Class1();
              this.add(class1);
              class1.setLocation(300, 300);
         }
         
    }
    Does someone have a solution ?
    Thanks in advance for your future help
  • 7. Re: Painting Over JTextField
    844235 Newbie
    Currently Being Moderated
    Up
  • 8. Re: Painting Over JTextField
    morgalr Explorer
    Currently Being Moderated
    841232,

    I have created your project in IDE, NetBeans 7.1 using Java 7 update 2 and the model that is generated when first started is the subject of your second png--the one you want showing the effect you desire. I've not made any changes, save it be using a JFrame constant to avoid additional imports. Perhaps just the Java version change?
    import java.awt.BasicStroke;
    import java.awt.Graphics;
    
    import javax.swing.border.StrokeBorder;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class JDrawOverJunk extends JPanel{
    
             private JTextField _tf1;
         
         public JDrawOverJunk() {
              StrokeBorder strokeBorder;
              BasicStroke basicStroke;
              
              this.setLayout(null);
              this.setSize(59, 59);
              
              basicStroke = new BasicStroke(1);
              strokeBorder = new StrokeBorder(basicStroke);
              this.setBorder(strokeBorder);
              
              _tf1 = new JTextField("T");
              _tf1.setEditable(false);
              this.add(_tf1);
              _tf1.setBounds(1, 1, 57, 57);
         }
         
         /**
          * Redefinition of the paint method to change the call order to
          * paintComponent, paintBorder and paintChildren
          * 
          * paintComponent is the last method called so a vertical line
          * is supposed to be drawn above the JTextField.
          */
         public void paint(Graphics g) {
              
              this.paintBorder(g);
              this.paintChildren(g); //< Paints the JTextField.
              this.paintComponent(g); //< Paints a vertical line.
         }
         
         /**
          * Redefinition of the paintComponent method to draw a vertical line.
          */
         protected void paintComponent(Graphics g) {
              g.drawLine(29, 0, 29, 58);
         }
    
        public static void main(String[] args) {
          JFrame frame;
          JDrawOverJunk class1;
              
          frame = new JFrame();
          frame.setSize(400, 400);
          frame.setLayout(null);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              
          class1 = new JDrawOverJunk();
          frame.add(class1);
          class1.setLocation(300, 300);
         
          frame.setVisible(true);
    
        }
    }

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points