为什么我的自定义 Swing 标签需要很长时间才能初始化?

发布于 2024-12-19 05:00:43 字数 1937 浏览 1 评论 0原文

我创建了 JLabel 的自定义子类。我有一个这样的实例,位于单个 JPanel 内、单个 JFrame 内。我没有重写paintComponent()方法;该类所做的只是当光标悬停在其上时更改背景颜色。

JFrame 立即加载,但 JPanel 在几秒钟内保持未绘制状态。我通过重写 paintComponent() 并添加一些调试 println() 语句来验证这是因为我的自定义类。

public void paintComponent(Graphics context)
{
    System.out.println("Painting...");
    super.paintComponent(context);
    System.out.println("Painted.");
}

奇怪的是,当我使用 Panel 而不是 JPanelLabel 而不是 JLabel 时,它会立即绘制。

这种滞后从何而来?

编辑:一些示例代码。实际上什么也没有画出来;查看控制台消息延迟。

import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.GridLayout;
import javax.swing.JPanel;

public class Example extends JLabel implements MouseListener
{
    private static final long serialVersionUID = 0;

    public Example()
    {
        super();
        System.out.println("Constructed.");
    }

    public void paintComponent(java.awt.Graphics g)
    {
        System.out.println("Painting component...");
        super.paintComponent(g);
        System.out.println("Painted.");
    }

    public void mouseEntered(MouseEvent event) { }
    public void mouseExited(MouseEvent event) { }
    public void mouseReleased(MouseEvent event) { }
    public void mousePressed(MouseEvent event) { }
    public void mouseClicked(MouseEvent event) { }

    public static void main(final String[] arguments)
    {
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 1));
        panel.add(new Example());

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(panel);
        frame.setVisible(true);
        System.out.println("Set visible.");
    }
}

I've made a custom subclass of JLabel. I have a single instance of this, inside a single JPanel, inside a single JFrame. I do not override the paintComponent() method; all the class does is change the background color when the cursor hovers over it.

The JFrame loads immediately, but for several seconds the JPanel is left undrawn. I verified that this is because of my custom class by overriding paintComponent() and adding some debug println() statements.

public void paintComponent(Graphics context)
{
    System.out.println("Painting...");
    super.paintComponent(context);
    System.out.println("Painted.");
}

The strange thing is, it's drawn instantly when I use Panel instead of JPanel or Label instead of JLabel.

Where is this lag coming from?

EDIT: Some example code. Nothing is actually drawn; look at the console message delay.

import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.GridLayout;
import javax.swing.JPanel;

public class Example extends JLabel implements MouseListener
{
    private static final long serialVersionUID = 0;

    public Example()
    {
        super();
        System.out.println("Constructed.");
    }

    public void paintComponent(java.awt.Graphics g)
    {
        System.out.println("Painting component...");
        super.paintComponent(g);
        System.out.println("Painted.");
    }

    public void mouseEntered(MouseEvent event) { }
    public void mouseExited(MouseEvent event) { }
    public void mouseReleased(MouseEvent event) { }
    public void mousePressed(MouseEvent event) { }
    public void mouseClicked(MouseEvent event) { }

    public static void main(final String[] arguments)
    {
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(1, 1));
        panel.add(new Example());

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(panel);
        frame.setVisible(true);
        System.out.println("Set visible.");
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

请止步禁区 2024-12-26 05:00:43

我的代码没有滞后:

我的 SSCCE:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class LabelTest extends JPanel {
   public LabelTest() {
      add(new MyLabel("Fubar!"));
   }

   private static void createAndShowGui() {
      LabelTest mainPanel = new LabelTest();

      JFrame frame = new JFrame("LabelTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

@SuppressWarnings("serial")
class MyLabel extends JLabel {
   private static final Color BACKGROUND_DEFAULT = new Color(200, 200, 255);
   private static final Color BACKGROUND_MOUSEOVER = new Color(255, 200, 200);
   private static final int PREF_W = 200;
   private static final int PREF_H = 100;

   public MyLabel(String text) {
      super(text, SwingConstants.CENTER);
      setOpaque(true);
      setBackground(BACKGROUND_DEFAULT);
      addMouseListener(new MouseAdapter() {

         @Override
         public void mouseEntered(MouseEvent arg0) {
            setBackground(BACKGROUND_MOUSEOVER);
         }

         @Override
         public void mouseExited(MouseEvent e) {
            setBackground(BACKGROUND_DEFAULT);
         }

      });
   }

   @Override
   public Dimension getPreferredSize() {
      int width = Math.max(super.getPreferredSize().width, PREF_W);
      int height = Math.max(super.getPreferredSize().height, PREF_H);
      return new Dimension(width, height);
   }
}

这向我表明问题不在于 JLabel 的背景通过 MouseListener 进行更改的概念,而是您的代码中的某处存在错误。在哪里?谁知道直到您发布可编译的可运行代码,一个 SSCCE,就像我上面发布的那样。

My code doesn't lag:

My SSCCE:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class LabelTest extends JPanel {
   public LabelTest() {
      add(new MyLabel("Fubar!"));
   }

   private static void createAndShowGui() {
      LabelTest mainPanel = new LabelTest();

      JFrame frame = new JFrame("LabelTest");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

@SuppressWarnings("serial")
class MyLabel extends JLabel {
   private static final Color BACKGROUND_DEFAULT = new Color(200, 200, 255);
   private static final Color BACKGROUND_MOUSEOVER = new Color(255, 200, 200);
   private static final int PREF_W = 200;
   private static final int PREF_H = 100;

   public MyLabel(String text) {
      super(text, SwingConstants.CENTER);
      setOpaque(true);
      setBackground(BACKGROUND_DEFAULT);
      addMouseListener(new MouseAdapter() {

         @Override
         public void mouseEntered(MouseEvent arg0) {
            setBackground(BACKGROUND_MOUSEOVER);
         }

         @Override
         public void mouseExited(MouseEvent e) {
            setBackground(BACKGROUND_DEFAULT);
         }

      });
   }

   @Override
   public Dimension getPreferredSize() {
      int width = Math.max(super.getPreferredSize().width, PREF_W);
      int height = Math.max(super.getPreferredSize().height, PREF_H);
      return new Dimension(width, height);
   }
}

This suggests to me that the problem isn't in the concept of a JLabel whose background changes via a MouseListener, but rather you've got a bug somewhere in your code. Where? Who knows until you post compilable runnable code, an SSCCE, like the one I've posted above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文