【问题标题】:Java JOptionPane custom draw on backgroundJava JOptionPane 在背景上自定义绘制
【发布时间】:2016-07-10 20:53:29
【问题描述】:

我用 Swing GUI 制作了一个 Java 桌面应用程序。在菜单栏中有一个“关于”条目。单击此“关于”菜单项时,使用 JOptionPane.showMessageDialog(...) 显示一个 JDialog,其中带有一个图标、关于我的程序的文本和一个“确定”按钮以关闭对话框。

我想绘制一个或多个在对话框背景中移动并改变颜色的球(圆)的效果。

使用@Titus 的解决方案更新代码:

自定义 JOptionPane 类:

class MyEffectPane extends JOptionPane {

    public MyEffectPane(String message, int type){
        super(message, type);

        makeOpa(this);
    }

    // needed to make the drawings visible
    void makeOpa(JComponent comp){
        for(Component c : comp.getComponents()){
            if(c instanceof JPanel){
                JPanel p = (JPanel)c;
                p.setOpaque(false);
                makeOpa(p);
            }
        }
    }


    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int width = getWidth();
        int height = getHeight();

        g.setColor(Color.BLACK);

        g.fillOval(width/2-50, height/2-50, 50, 50);
    }
}

调用/显示对话框:

MyEffectPane pane = new MyEffectPane("message....", JOptionPane.INFORMATION_MESSAGE);
    JDialog dialog = pane.createDialog(this, "About");
    //dialog.setIconImage(icon.getImage());
    dialog.setVisible(true);
    dialog.dispose();

【问题讨论】:

  • showMessageDialog 方法是 static(您不能覆盖它),它会创建自己的 JOptionPane 对象。
  • @Titus 谢谢,你知道我的问题的解决方案吗?
  • 调试语句不要使用System.out.println()。它不一定会在每次执行时打印一行,因为System.out 是一个缓冲流。而是使用System.err.println() 来保证立即输出。
  • @JoeCoder 谢谢!我不知道..

标签: java swing user-interface joptionpane jdialog


【解决方案1】:

showMessageDialog 方法是 static(您不能覆盖它),它会创建自己的 JOptionPane 对象。

您可以重现 showMessageDialog 正在做的事情,即:

 /**
 * This method shows an INFORMATION_MESSAGE type message dialog.
 *
 * @param parentComponent The component to find a frame in.
 * @param message The message displayed.
 */
public static void showMessageDialog(Component parentComponent, Object message){
  JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
  JDialog dialog = pane.createDialog(parentComponent, null);
  dialog.show();   
}

你可以把它改成这样:

MyEffectPane pane = new MyEffectPane("message....", JOptionPane.INFORMATION_MESSAGE);
JDialog dialog = pane.createDialog(this, null);
dialog.show();

此外,您必须将此构造函数添加到您的 MyEffectPane 类中:

MyEffectPane(String message, int type){
    super(message, type);
}

【讨论】:

  • 谢谢!!!!这完美!我刚刚添加了一些代码,以便 JDialog 的组件不会使用 setOpaque(false) 隐藏我的绘图。我将使用工作代码更新帖子。
【解决方案2】:

我想绘制一个或多个在对话框背景中移动并改变颜色的球(圆)的效果。

不要使用 JOptionPane。

相反,您可以创建您的自定义JDialog。然后你会在你的对话框中添加一个 JPanel 来进行自定义绘画。

阅读 Custom Painting 上的 Swing 教程部分了解更多信息。

注意,在进行自定义绘制时,您的覆盖 paintComponent(..),而不是 paint(...)。

或者,如果您愿意,您可以将自定义 JPanel 添加到 JOptionPane。无论如何,关键是在 JPanel 上进行自定义绘画。

【讨论】:

  • 也谢谢你,但@Titus 的方法效果很好。我试过这个,但问题是你必须对 JDialog 中的文本、图标和 OK 按钮进行调整才能看起来不错。添加一个面板是可行的,但是您只有一个可以绘制的小区域,它是普通 JDialog 的文本所在的区域。
【解决方案3】:

您不能覆盖 JOptionPane。它是静态的,主要用于方便创建确认选项。

对于你想要的,你可以使用 JDialog。 JDialog 使您可以更轻松地创建具有自定义内容的弹出窗口。

由于您已经在尝试使用 JOptionPane,我假设您有一个触发 JOptionPane 的包含面板。您所要做的就是:

  1. 使用SwingUtilities.getWindowAncestor(panel) 从父面板中提取包含窗口。
  2. 使用提取的窗口创建JDialog:JDialog dialog = new JDialog(containerWindow)
  3. 根据自己的喜好自定义 JDialog 功能。

您的部分代码应如下所示:

Window containerWindow = SwingUtilities.getWindowAncestor(panel);
JDialog dialog = new JDialog(containerWindow);
dialog.setLayout(new BorderLayout());
dialog.setLocationRelativeTo(containerWindow);
dialog.setResizeable(false);
dialog.add(effectPanel, BorderLayout.CENTER);

在这种情况下 effectPanel 是您自己的自定义面板,其中包含图形和您想做的一切。这不是编写代码的最佳方式,但我将其写下来只是作为您的示例。您可以在这里查看更多 JDialog 的功能:JDialog

【讨论】:

  • 谢谢!这看起来很有趣!我认为由于使用了 BorderLayout,生成的 JDialog 看起来不太好,这可能是一个问题,因此例如 OK 按钮将在底部获得全宽大小。还是我想错了?但是@Titus 方法效果很好..
  • 我只以 BorderLayout 为例。你可以使用任何你需要的布局。如果您找到了更简单的解决方案,那就太好了!如果你需要对选项面板做的事情变得有点复杂,那么 JDialog 可能会更有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多