如何在 setLocation 之后不重绘我的 JLabel

How don't repaint after setLocation my JLabel

我正在为我的菜单制作动画。我创建了一个动画视频:https://youtu.be/wG6AFMj1ZYI 如您所见,动画重绘我的帧非常困难:'(。修改我的 JLabel 后我不会重绘!

private synchronized void animationButtonExited(JLabelFirstPosition button) {
    if (button.getActual_thread_running().isAlive()) {
        button.getActual_thread_running().interrupt();
    }
    Thread t = new Thread(() -> {
        SwingUtilities.invokeLater(() -> {
            button.setFont(new Font(null, 0,
                    (int) (this.racio_width < this.racio_height
                            ? (int) (button.getFirstFontSize() * this.racio_width)
                            : (button.getFirstFontSize() * this.racio_height))));
            button.setSize((int) (button.getFirstSize().getWidth() * this.racio_width),
                    (int) (button.getFirstSize().getHeight() * this.racio_height));
        });
        try {
            while (button.getLocation().getX() > button.getFirstX() * this.racio_width) {
                SwingUtilities.invokeLater(() -> {
                    button.setLocation((int) ((button.getLocation().getX() - 1)),
                            (int) (button.getFirstY() * this.racio_height));
                });
                Thread.sleep(6);
            }
        } catch (InterruptedException e1) {
        }
    });
    t.start();
    if (!button.getActual_thread_running().isAlive()) {
    } else {
        button.getActual_thread_running().interrupt();
    }
    button.setActual_thread_running(t);
}

private synchronized void animationButtonEntered(JLabelFirstPosition button) {
    if (button.getActual_thread_running().isAlive()) {
        button.getActual_thread_running().interrupt();
    }
    Thread t = new Thread(() -> {
        SwingUtilities.invokeLater(() -> {
            button.setFont(new Font("", 1,
                    (int) (this.racio_width < this.racio_height
                            ? (int) (button.getFirstFontSize() * this.racio_width)
                            : ((button.getFirstFontSize() + 5) * this.racio_height))));
            button.setSize((int) ((button.getFirstSize().getWidth() + 20) * this.racio_width),
                    (int) (button.getFirstSize().getHeight() * this.racio_height));
        });
        try {
            while (button.getLocation().getX() <= (button.getFirstX() + 20) * this.racio_width) {
                SwingUtilities.invokeLater(() -> {
                    button.setLocation((int) ((button.getLocation().getX() + 1)),
                            (int) (button.getFirstY() * this.racio_height));
                });
                Thread.sleep(3);
            }
        } catch (InterruptedException e1) {
        }
    });
    t.start();
    if (!button.getActual_thread_running().isAlive()) {
    } else {
        button.getActual_thread_running().interrupt();
    }
    button.setActual_thread_running(t);
}

我的 fps 计算器检测方法“paintComponent”被调用了多少次。

谢谢!

这是创建菜单的一种方法,其中 mouse-over 使 selection 脱颖而出。

MouseListener class 具有我们将在本示例中使用的三种方法。 mouseEntered 方法检测鼠标何时进入 Swing 组件,在本例中为 JLabelmouseExited 方法检测鼠标何时退出 Swing 组件。

mousePressed 方法检测何时按下鼠标按钮。这允许我们使用一个 JLabel 到 select 一个选项。

设置 JFrame 有点棘手。我们不希望我们创建的 JPanels 不断改变大小。

所以,我们经历了以下过程:

  1. 用更大的字体创建菜单JPanel

  2. 打包JFrame

  3. 获取菜单的大小 JPanel 并使其成为菜单的首选大小 JPanel

  4. 在我们使 JFrame 可见之前将字体改回较小的字体。

这是我使用的代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class MouseoverExample implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new MouseoverExample());
    }
    
    private Font font;
    
    private JLabel optionLabel;
    private JLabel option1Label;
    private JLabel option2Label;
    private JLabel option3Label;    
    
    private JPanel menuPanel;

    @Override
    public void run() {
        JFrame frame = new JFrame("Mouseover Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createMenuPanel(), BorderLayout.BEFORE_LINE_BEGINS);
        frame.add(createDummyPanel(), BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        
        menuPanel.setPreferredSize(menuPanel.getSize());
        updateFont();
        
        frame.setVisible(true);
    }
    
    private JPanel createMenuPanel() {
        JPanel outerPanel = new JPanel();
        outerPanel.setLayout(new FlowLayout());
        
        menuPanel = new JPanel();
        menuPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        menuPanel.setLayout(new GridLayout(0, 1, 5, 5));
        
        font = menuPanel.getFont().deriveFont(18f);
        Font boldFont = font.deriveFont(Font.BOLD).deriveFont(24f);
        ExampleListener listener = new ExampleListener(font, boldFont);
        
        option1Label = new JLabel("Option 1");
        option1Label.setFont(boldFont);
        option1Label.addMouseListener(listener);
        menuPanel.add(option1Label);
        
        option2Label = new JLabel("Option 2");
        option2Label.setFont(boldFont);
        option2Label.addMouseListener(listener);
        menuPanel.add(option2Label);
        
        option3Label = new JLabel("Option 3");
        option3Label.setFont(boldFont);
        option3Label.addMouseListener(listener);
        menuPanel.add(option3Label);
        
        outerPanel.add(menuPanel);
        
        return outerPanel;
    }
    
    private void updateFont() {
        option1Label.setFont(font);
        option2Label.setFont(font);
        option3Label.setFont(font);
    }
    
    private JPanel createDummyPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setPreferredSize(new Dimension(400, 400));
        
        optionLabel = new JLabel(" ");
        panel.add(optionLabel);
        
        return panel;
    }
    
    public class ExampleListener extends MouseAdapter {
        
        private Font enterFont;
        private Font exitFont;

        public ExampleListener(Font exitFont, Font enterFont) {
            this.exitFont = exitFont;
            this.enterFont = enterFont;
        }

        @Override
        public void mouseEntered(MouseEvent event) {
            JLabel label = (JLabel) event.getSource();
            label.setFont(enterFont);
        }

        @Override
        public void mouseExited(MouseEvent event) {
            JLabel label = (JLabel) event.getSource();
            label.setFont(exitFont);
        }
        
        @Override
        public void mousePressed(MouseEvent event) {
            JLabel label = (JLabel) event.getSource();
            String optionText = label.getText();
            optionLabel.setText(optionText + " displayed");
        }

    }

}