【问题标题】:Graphics on top of a Panel面板顶部的图形
【发布时间】:2012-02-28 22:09:52
【问题描述】:

我在上面有 JLabel 的面板上绘制的图形有问题。我正在使用自定义paintComponent(Graphics g) 方法在面板上绘制字符串。我希望字符串显示在 JLabel 的顶部而不是 JLabel 的下方,这是当前正在发生的事情。如果您想查看它,这里是 paintComponent 方法:

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

我不太喜欢图形,但我需要学习解决这个问题。

【问题讨论】:

    标签: java swing jpanel jlabel paintcomponent


    【解决方案1】:

    为此,我认为您必须覆盖paint 或paintChildren,并在此处绘制文本:

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

    但更好的解决方案是使用 JLayeredPane 或 glasspane 来实现此效果。

    【讨论】:

    • paint / paintComponent / paintChildren +1
    • @mKorbel 你通常不喜欢重写paint 方法;)
    • @GETah:他没有,我也没有,但有时需要这样做,例如在制作淡入淡出的 JPanel 时。但同样,对于这个问题,我不会这样做,而是使用 JLayeredPane 对组件进行分层。
    • @HovercraftFullOfEels 很好的答案,+1!
    • @HoverCraftOfEels 谢谢您,您的建议非常好,我喜欢您制作该应用程序以向我展示其工作原理的方式。非常欣赏它。在这种情况下,虽然我不能使用 JLayeredPane 或者我会。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多