在屏幕上显示消息

时间:2014-10-20 19:20:37

标签: java swing

我想在按下按钮时在屏幕上显示一条消息。该消息不应该有任何窗口,应该在屏幕的中心显示任何内容。有点像here。我将如何实现这样的效果?

我尝试过到处寻找,但问题的性质不会产生结果。感谢任何人帮助我指出正确的方向。

更新: For those wondering. This is the project I am working on, thanks MadProgrammer for your help. You saved my eyes.

3 个答案:

答案 0 :(得分:3)

我可以想到至少有三种方法可以在Swing中做到这一点......

玻璃面板

如果您只是想在当前帧上显示内容,那么您可以使用当前帧玻璃窗格......

GlassPane

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class OverlayTest {

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

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

                final OverlayPane overlay = new OverlayPane();
                JButton show = new JButton("Show");
                show.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        overlay.setVisible(true);
                    }
                });

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setGlassPane(overlay);
                frame.setLayout(new GridBagLayout());
                frame.add(show);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class OverlayPane extends JPanel {

        private JLabel label;

        public OverlayPane() {
            setLayout(new GridBagLayout());
            label = new JLabel("1");
            label.setFont(label.getFont().deriveFont(Font.BOLD, 96f));
            add(label);
            setOpaque(false);
        }

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

    }

}

了解如何使用How to Use Root Panes

JLayedPane

如果您想在当前帧中的特定组件上显示内容,那么您可以利用JLayeredPane,它的作用很像组件的玻璃窗格......

有关详细信息,请参阅How to Decorate Components with the JLayer Class

未修饰的框架

Transparent Frame

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class OverlayTest2 {

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

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

                final JFrame masterFrame = new JFrame("Testing");

                final OverlayPane overlay = new OverlayPane();
                JButton show = new JButton("Show");
                show.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {

                        JFrame frame = new JFrame();
                        frame.setUndecorated(true);
                        frame.setBackground(new Color(0, 0, 0, 0));
                        frame.add(new OverlayPane());
                        frame.pack();
                        frame.setLocationRelativeTo(masterFrame);
                        frame.setVisible(true);

                    }
                });

                masterFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                masterFrame.setGlassPane(overlay);
                masterFrame.setLayout(new GridBagLayout());
                masterFrame.add(show);
                masterFrame.pack();
                masterFrame.setLocationRelativeTo(null);
                masterFrame.setVisible(true);
            }
        });
    }

    public class OverlayPane extends JPanel {

        private JLabel label;

        public OverlayPane() {
            setLayout(new GridBagLayout());
            label = new JLabel("1");
            label.setFont(label.getFont().deriveFont(Font.BOLD, 96f));
            add(label);
            setOpaque(false);
        }

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

    }

}

请参阅How to Create Translucent and Shaped Windows

现在,如果你想要填充窗口,那么删除行frame.setBackground(new Color(0, 0, 0, 0));,这就是框架透明的原因。

答案 1 :(得分:1)

这是一个难以回答的问题,因为它并没有真正显示你试图做的事情,但我会尝试将我的评论建议点亮并向你展示一个可能更接近你想要的简单例子

创建一个简单的FXML文件(用于JavaFX),该文件定义了一个带有标签的窗格。 给标签一个ID并为其分配一个控制器。

示例文件(TestDialog.fxml),定义带有标签的简单窗格:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane minHeight="111.0" mouseTransparent="false" opacity="1.0" prefHeight="111.0" prefWidth="244.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="MyController">
  <children>
    <Label fx:id="textLabel" layoutX="22.0" layoutY="25.0" minHeight="13.0" prefHeight="61.0" prefWidth="200.0" text="SOME TEXT" textFill="BLACK">
      <font>
        <Font size="36.0" />
      </font>
    </Label>
  </children>
</AnchorPane>

在控制器类中,定义一个允许您关闭窗格的函数。根据您的需要,您可能想要或不想要更多。

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.stage.Stage;

import java.net.URL;
import java.util.ResourceBundle;
public class MyController implements Initializable {
    @FXML
    private Label textLabel;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

    }

    public void close() {
        ((Stage)textLabel.getScene().getWindow()).close();
    }
}

然后,在主代码中,显示窗口。此示例将其作为顶级打开,但您也可以将其用作子级。

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class Main extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader myLoader = new FXMLLoader(getClass().getResource("TestDialog.fxml"));
        Parent root = (Parent)myLoader.load();
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.initStyle(StageStyle.UNDECORATED);  // this style sets the stage to have no border or buttons/title bar
        stage.setResizable(false);
        stage.show();
    }

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

结果如下所示

Dialog with no borders

*请注意,此代码(如编写)不提供关闭对话框的方法。这是一个留给你的练习。这只是一个用来向你展示效果的例子。

答案 2 :(得分:1)

你可以创建一个HBox并用透明背景颜色(-fx-background-color:transparent;)居中,然后在你的初始化函数中隐藏它。在按下按钮时,您可以显示它并给它一个计时器并将其隐藏在计时器的末尾,或者放一个小的&#34; x&#34;使用setOnAction(event - &gt; {myText.hide()})在右上角或底部或任何地方。只是一个想法,当你想要做的只是显示一些文字时,这可能太复杂了。