简体   繁体   English

组件仅在悬停时绘制

[英]Components Only get drawn when hovered over

Can someone explain why my components only get drawn when I hover over where they are supposed to be? 有人可以解释为什么我的组件只有在我将它们悬停在它们应该的位置时才会被绘制出来吗?

I setup a borderless frame than can be dragged anywhere and I'm trying to create an exit button at the top right but it doesn't get drawn until I hover over it. 我设置了一个无边框,而不是可以在任何地方拖动,我正在尝试在右上角创建一个退出按钮但是在我将鼠标悬停在它上面之前它不会被绘制。 I paint to the JFrame a background image, then draw my button and set the whole thing visible. 我在JFrame上绘制一个背景图像,然后绘制我的按钮并将整个事物设置为可见。

import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GUI extends JFrame
{
    private Image Background = null;
    private static Point Offset = new Point();

    public GUI() {
        this.setUndecorated(true);
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        AddListeners();
        SetCustomTheme();
        LoadBackground();
        Layout();
        pack();
        this.setSize(300, 300);
        this.setVisible(true);
    }

    private void Layout() {
        GroupLayout Info = new GroupLayout(this.getContentPane());
        this.getContentPane().setLayout(Info);
        JButton Button = new JButton();

        Info.setHorizontalGroup(
            Info.createSequentialGroup()
               .addComponent(Button)
         );

        Info.setVerticalGroup(
            Info.createParallelGroup()
                .addComponent(Button)
        );
    }

    private void SetCustomTheme() {
        try {
            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
        }
    }

    private void LoadBackground() {
        try {
            Background = ImageIO.read(getClass().getResource("Images/meh.png"));
        } catch (Exception Ex) {

        }
    }

    private void SetCustomIcon() {
        Image Icon = Toolkit.getDefaultToolkit().getImage("Images/lol.jpg");
        setIconImage(Icon);
    }

    private void AddListeners() {
        this.addMouseListener(new MouseAdapter() {
            @Override public void mousePressed(MouseEvent e) {
              Offset.x = e.getX();
              Offset.y = e.getY();
            }
          });

        this.addMouseMotionListener(new MouseMotionAdapter() {
            @Override public void mouseDragged(MouseEvent e) {
              Point p = getLocation();
              setLocation(p.x + e.getX() - Offset.x, p.y + e.getY() - Offset.y);
            }
          });
    }

    @Override public void paint(Graphics g) {
        g.drawImage(Background, 0,0,this.getWidth(),this.getHeight(), null);
    }
}
  1. All interactions with the UI must be executed from within the Event Dispatching Thread 必须在Event Dispatching Thread中执行与UI的所有交互
  2. You should avoid extending from top level containers, like JFrame , instead, use JPanel instead. 您应该避免从顶级容器(如JFrame扩展,而是使用JPanel
  3. Failing to honor the paint chain contract is preventing any child components from begin painted 未能遵守paint链合同是防止任何儿童组件开始绘画
  4. The preferred method to override for performing custom painting is paintComponent 覆盖执行自定义绘制的首选方法是paintComponent

You might like to have a read through 您可能希望阅读

Try something like this instead; 尝试这样的事情;

public class BadPaint01 {

    public static void main(String[] args) {
        new BadPaint01();
    }

    public BadPaint01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                Image Icon = Toolkit.getDefaultToolkit().getImage("Images/lol.jpg");
                frame.setIconImage(Icon);
                frame.setUndecorated(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new GUI());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class GUI extends JPanel {

        private Image Background = null;
        private static Point Offset = new Point();

        public GUI() {
            AddListeners();
            SetCustomTheme();
            LoadBackground();
        }

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

        private void Layout() {
            GroupLayout Info = new GroupLayout(this);
            setLayout(Info);
            JButton Button = new JButton();

            Info.setHorizontalGroup(
                    Info.createSequentialGroup()
                    .addComponent(Button));

            Info.setVerticalGroup(
                    Info.createParallelGroup()
                    .addComponent(Button));
        }

        private void SetCustomTheme() {
            try {
                UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }
        }

        private void LoadBackground() {
            try {
                Background = ImageIO.read(getClass().getResource("Images/meh.png"));
            } catch (Exception Ex) {
            }
        }

        private void AddListeners() {
            this.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    Offset.x = e.getX();
                    Offset.y = e.getY();
                }
            });

            this.addMouseMotionListener(new MouseMotionAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    Point p = getLocation();
                    setLocation(p.x + e.getX() - Offset.x, p.y + e.getY() - Offset.y);
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            g.drawImage(Background, 0, 0, this.getWidth(), this.getHeight(), null);
        }
    }
}

You also might like to have read through Code Conventions for the Java Programming Language , you're not going to make any friends by ignoring them ;) 您也可能希望阅读Java编程语言的代码约定,而不是通过忽略它们来建立任何朋友;)

If I remember well, ToolKit.getImage returns an Image which may not be completely loaded. 如果我记得很清楚, ToolKit.getImage返回一个可能无法完全加载的Image When you hover over it, it probably has been loaded in the background meanwhile. 当您将鼠标悬停在它上面时,它可能已同时加载到后台。 Instead do this (similar to your line for Background): 而是这样做(类似于你的背景线):

ImageIcon Icon = new ImageIcon(ImageIO.read(getClass().getResource("Images/lol.png")));
setIconImage(Icon);

(For better understanding you may want to search for MediaTracker , which I believe was used to make sure, that the image is loaded completely.) (为了更好地理解,您可能希望搜索MediaTracker ,我相信这是用来确保图像完全加载的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM