Question

I am having trouble with the Graphics that I am drawing on a Panel which has a JLabel on top of it. I am using a custom paintComponent(Graphics g) method to draw a String on the Panel. I want the string to show on top of the JLabel instead of under the JLabel, which is what is currently happening. Here is the paintComponent method if you want to see it:

public void paintComponent(Graphics g){
    super.paintComponent(g);

    if(a.shouldAnnotate()){
        FontMetrics size= g.getFontMetrics(); 
        if(getWidth()>=(a.dispX()+size.stringWidth(a.annotationText()))){
            g.setColor(Color.white);
            g.fillRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
            g.setColor(Color.black);
            g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(a.annotationText())+5,15);
            g.drawString(a.annotationText(), a.dispX(), a.dispY());
        }else{
            String sub="";
            int letters=0;
            g.setColor(Color.white);
            g.fillRect(a.dispX()-3,a.dispY()-12,getWidth(),15);
            g.setColor(Color.black);

            for(int i=0;i<a.annotationText().length();i++){
                if(a.dispX()+letters+16<=getWidth()){
                    sub+=a.annotationText().substring(i,i+1);
                    letters=size.stringWidth(sub);
                }else{
                    sub=sub+"...";
                    i=a.annotationText().length();
                }
            }
            g.drawRect(a.dispX()-3,a.dispY()-12,size.stringWidth(sub)+3,15);
            g.drawString(sub,a.dispX(),a.dispY());
        }
    }
}

I don't like graphics much but I need to learn the fix of this problem.

Was it helpful?

Solution

To do this I think that you must either override paint or paintChildren, and draw your text there:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;

import javax.swing.*;

@SuppressWarnings("serial")
public class DrawOverLabel extends JPanel {
   private static final int PREF_W = 500;
   private static final int PREF_H = 100;
   private static final Font TEXT_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 32);
   private static final int LABEL_COUNT = 40;

   public DrawOverLabel() {
      for (int i = 0; i < LABEL_COUNT; i++) {
         JLabel label = new JLabel("Label");
         label.setForeground(Color.green);
         label.setFont(label.getFont().deriveFont(Font.BOLD, 20));
         add(label);
      }
   }

   @Override
   public void paint(Graphics g) {
      super.paint(g);

      g.setColor(Color.blue);
      g.setFont(TEXT_FONT);
      g.drawString("in paint", 20, 30);

//      super.paint(g);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);

      g.setColor(Color.red);
      g.setFont(TEXT_FONT);
      g.drawString("in paintComponent", 20, 60);

//      super.paintComponent(g);
   }

   @Override
   protected void paintChildren(Graphics g) {
      super.paintChildren(g);

      g.setColor(Color.gray);
      g.setFont(TEXT_FONT);
      g.drawString("in paintChildren", 20, 100);

//       super.paintChildren(g);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("DrawOverLabel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new DrawOverLabel());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

But a better solution is to use a JLayeredPane or the glasspane for this effect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top