如何通过Java中的脚本弹出文本框(或工具提示) [英] How to pop up a text box(or tooltip) via script in Java

查看:110
本文介绍了如何通过Java中的脚本弹出文本框(或工具提示)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常具体的问题: 我希望能够通过方法调用在屏幕上给定位置在方法调用上弹出一定时间的文本提示(可以说任何东西)(例如逻辑在talk方法中),然后淡去.我该怎么办?有没有办法通过JTooltip做到这一点?还是我必须深入JNA以获得我想要的东西?

I have a very specific question: I want to be able to, via a method call, popup a tooltip with text(it could say anything) in a given location on the screen for a certain amount of time on method call(say the logic is in a talk method) and fades away. How could I go about that? Is there a way to do it via JTooltip? Or would I have to dive into JNA to get what I want?

我应该提一下,我希望工具提示在给定的位置弹出文本,而不会像在弹出窗口一样将鼠标悬停在提示上.

I should mention I want the tooltip to popup with text in a given location without the cue of a mouse over, like a popup.

此外,如果工具提示不是实现我想要的正确方法(我希望我已明确指出),还有没有更有效的替代方法?

Also, in case a tooltip is not the right way to go about what I want (which I hope I made clear), is there a more effective alternative?

推荐答案

有几种方法可以实现.一种可能的方法是使用透明的JWindow和Swing的Timer

There are few ways this might be achieved. One possible way is through the use of a transparent JWindow and a Swing Timer

基本上,此操作将创建一个JWindow,将其背景色设置为完全透明,从而创建一个透明窗口.然后,它使用简单的BackgroundPane(以呈现漂亮的背景)和MessagePane来保存实际的消息.您可以在一个面板中完成此操作,但是我喜欢它提供的灵活性.

Basically, what this does is creates a JWindow, set's it's background color to fully transparent, making a transparent window. It then uses simple BackgroundPane (to render a nice background) and MessagePane to hold the actual message. You can do this in one panel, but I like the flexibility this affords me.

现在,就我个人而言,我将创建一个更简单的API,该API可以构建弹出窗口并创建具有可变延迟的Timer,但您明白了

Now, personally, I would create a simpler API which could build the popup window and create a Timer with a variable delay, but you get the idea

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class PopupMessageWindow {

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

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

                final JWindow frame = new JWindow();
                frame.setBackground(new Color(0, 0, 0, 0));
                BackgroundPane pane = new BackgroundPane();
                pane.setMessage("Boo, This is a popup...");
                frame.add(pane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.setAlwaysOnTop(true);

                Timer timer = new Timer(10000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        frame.dispose();
                        System.exit(0);
                    }
                });
                timer.setRepeats(false);
                timer.start();
            }
        });
    }

    public class BackgroundPane extends JPanel {

        private MessagePane messagePane;

        public BackgroundPane() {
            setBorder(new EmptyBorder(40, 40, 40, 40));
            messagePane = new MessagePane();
            setLayout(new BorderLayout());
            add(messagePane);
            setOpaque(false);
        }

        public void setMessage(String msg) {
            messagePane.setMessage(msg);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
            LinearGradientPaint glp = new LinearGradientPaint(
                            new Point(0, 0),
                            new Point(0, getHeight()),
                            new float[]{0f, 1f},
                            new Color[]{Color.GRAY, Color.BLACK});
            RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
            g2d.setPaint(glp);
            g2d.fill(frame);
            g2d.setColor(Color.WHITE);
            g2d.draw(frame);
        }

    }

    public class MessagePane extends JPanel {

        private JLabel label;

        public MessagePane() {
            setOpaque(false);
            label = new JLabel();
            label.setForeground(Color.WHITE);
            setLayout(new GridBagLayout());
            add(label);
        }

        public void setMessage(String msg) {
            label.setText(msg);
        }

    }

}

您可以在背景面板上使用AlphaComposite来创建半透明背景

You could play with a AlphaComposite on the background panel to create a semi transparent background

使用50%AlphaComposite

已更新

您可以使用工厂或构建器模式来提供简单的API,例如...

You could use a factory or builder pattern to provide a simple API, for example...

new PopupBuilder().at(new Point(100, 100)).withMessage("Hello").withDelay(5000).show();

构建器将收集您要指定的属性,在未设置它们的地方提供默认值,然后显示最终弹出窗口.

The builder would collect the properties you want to specify, provide defaults where you didn't set them and then would show the final popup.

基本思想是,当您调用show时,它将收集属性并构建类似于构造函数当前工作方式的窗口...

The basic idea is when you call show, it would collect the properties and build the window similar to how the constructor works right now...

已更新,带有弹出窗口

这是(可能在顶部之上)如何产生淡入/淡出效果的示例.该示例保证消息在指定的延迟时间内将在屏幕上显示(完整)

This is (a somewhat over the top) example of how you might be able to produce a fading in/out effect. The example guarantees that the message will be on the screen (full) for at specified delay period

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class PopupMessageExample {

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

    public PopupMessageExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                new PopupMessageBuilder().withDelay(10000).withMessage("Hello, this is a fading message").show();
            }
        });
    }

    public class PopupMessageBuilder {

        private int delay;
        private Point location;
        private String message;

        private long startTime;
        private Timer fadeTimer;

        public PopupMessageBuilder at(Point p) {
            this.location = p;
            return this;
        }

        public PopupMessageBuilder withDelay(int delay) {
            this.delay = delay;
            return this;
        }

        public PopupMessageBuilder withMessage(String msg) {
            this.message = msg;
            return this;
        }

        public PopupMessageBuilder show() {

            final JWindow frame = new JWindow();
            frame.setOpacity(0f);
            frame.setBackground(new Color(0, 0, 0, 0));
            BackgroundPane pane = new BackgroundPane();
            pane.setMessage(message);
            frame.add(pane);
            frame.pack();
            if (location == null) {
                frame.setLocationRelativeTo(null);
            } else {
                frame.setLocation(location);
            }
            frame.setVisible(true);
            frame.setAlwaysOnTop(true);

            new FadeTimer(frame, 1000, 0f, 1f, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    Timer timer = new Timer(delay, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            new FadeTimer(frame, 1000, 1f, 0f, new ActionListener() {
                                @Override
                                public void actionPerformed(ActionEvent e) {
                                    frame.dispose();
                                }
                            }).start();
                        }
                    });
                    timer.setRepeats(false);
                    timer.start();
                }
            }).start();

            return this;
        }

        public class FadeTimer extends Timer implements ActionListener {

            private final float startAt;
            private final float endAt;
            private final int duration;
            private long startTimer;

            private ActionListener endListener;

            private Window window;

            public FadeTimer(Window window, int duration, float startAt, float endAt, ActionListener endListener) {
                super(5, null);
                addActionListener(this);
                this.duration = duration;
                this.startAt = startAt;
                this.endAt = endAt;
                this.window = window;

                this.endListener = endListener;
            }

            @Override
            public void start() {
                startTime = System.currentTimeMillis();
                super.start();
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                long now = System.currentTimeMillis();
                long lapsed = now - startTime;
                float opacity = startAt;
                if (lapsed >= duration) {
                    opacity = endAt;
                    ((Timer) e.getSource()).stop();
                    if (endListener != null) {
                        endListener.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "stopped"));
                    }
                } else {
                    float progress = (float) lapsed / (float) duration;
                    float distance = endAt - startAt;
                    opacity = (float) (distance * progress);
                    opacity += startAt;
                }
                window.setOpacity(opacity);
            }

        }

        public class BackgroundPane extends JPanel {

            private MessagePane messagePane;

            public BackgroundPane() {
                setBorder(new EmptyBorder(40, 40, 40, 40));
                messagePane = new MessagePane();
                setLayout(new BorderLayout());
                add(messagePane);
                setOpaque(false);
            }

            public void setMessage(String msg) {
                messagePane.setMessage(msg);
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
                g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
                LinearGradientPaint glp = new LinearGradientPaint(
                                new Point(0, 0),
                                new Point(0, getHeight()),
                                new float[]{0f, 1f},
                                new Color[]{Color.GRAY, Color.BLACK});
                RoundRectangle2D frame = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
                g2d.setPaint(glp);
                g2d.fill(frame);
                g2d.setColor(Color.WHITE);
                g2d.draw(frame);
            }

        }

        public class MessagePane extends JPanel {

            private JLabel label;

            public MessagePane() {
                setOpaque(false);
                label = new JLabel();
                label.setForeground(Color.WHITE);
                setLayout(new GridBagLayout());
                add(label);
            }

            public void setMessage(String msg) {
                label.setText(msg);
            }

        }

    }

}

现在,您可能还可以通过更改框架的最大不透明度级别来执行此操作,但是,如果更改BackgroundPane

Now, you probably also do this by changing the maximum opacity level of the frame, but, if you change the paintComponent of the BackgroundPane

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g.create();
    AlphaComposite alpha = AlphaComposite.SrcOver.derive(0.75f);
    g2d.setComposite(alpha);

您还可以使弹出消息过于透明.此方法只会影响背景,而不会影响消息文本...

you can also effect the over opacity of the popup message. This method will only effect the background, not the message text...

这篇关于如何通过Java中的脚本弹出文本框(或工具提示)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆