【问题标题】:java swing hide and show JOptionPane programmaticallyjava swing 以编程方式隐藏和显示 JOptionPane
【发布时间】:2022-01-17 19:08:02
【问题描述】:

我一直在研究以编程方式隐藏和显示与我们的主 GUI 框架相关联的 Swing 对话框。我查看的许多答案都使用 getOwnedWindows() 方法来获取与框架关联的所有子项,然后将可见性设置为 false。这非常适合隐藏对话框。但是,我也想重新打开可见性,当我这样做时,我看不到对话框的任何按钮或图标。只是带有标题的对话框的框架。

总结一下。 我创建了一个 JOptionPane 对话框:

JOptionPane.showConfirmDialog( this, "Eggs are not green!", "True Statement", JOptionPane.YES_NO_CANCEL_OPTION );

我将对话框可见性设置为 false

      for (Window win : getOwnedWindows())
      {
         win.setVisible(false);
      }

我稍等片刻,然后将可见性设置为 true

      for (Window win : getOwnedWindows())
      {
         win.setVisible(true);
      }

我看到了这个:

这是完整的玩具程序。我尝试在子窗口上重新验证并重新绘制。那没有效果。

import javax.swing.*;
import java.awt.*;

import static java.util.concurrent.TimeUnit.SECONDS;

public class DialogOnTimeoutCloser extends JFrame
{
   DialogOnTimeoutCloser()
   {
      super( "JOptionPane programmatic visibillity test." );

      SwingUtilities.invokeLater(() -> {

         getContentPane().setLayout( new FlowLayout() );
         setPreferredSize( new Dimension( 300, 300 ));
         setLocationRelativeTo(null);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         pack();
         setVisible(true);

         JOptionPane.showConfirmDialog( this, "Eggs are not green!", "True Statement", JOptionPane.YES_NO_CANCEL_OPTION );
      });
   }

   private void closeAllDialogs()
   {
      for (Window win : getOwnedWindows())
      {
         win.setVisible(false);
      }
   }

   private void openAllDialogs()
   {
      for (Window win : getOwnedWindows())
      {
         win.setVisible(true);
      }
   }

   public static void main(String[] args) throws InterruptedException
   {
      DialogOnTimeoutCloser dialogOnTimeoutCloser = new DialogOnTimeoutCloser();
      Thread.sleep(SECONDS.toMillis( 5 ));
      dialogOnTimeoutCloser.closeAllDialogs();
      Thread.sleep(SECONDS.toMillis( 5 ));
      dialogOnTimeoutCloser.openAllDialogs();
   }
}

【问题讨论】:

  • 我对你真正想要完成的事情感到困惑。如果您只想显示一条简单的消息,那么我会使用 JOptionPane.showMessageDialog() 。您不需要对可见性进行微观管理。
  • 另外,不要从事件调度线程的上下文之外修改 UI 的状态,Swing 不是线程安全的。你的想法没有意义(对我来说),你为什么要隐藏和显示一个模态对话框,重点是显示它并处理它

标签: java swing dialog joptionpane


【解决方案1】:

我建议您避免两次显示 JOptionPane,因为它是一次性对象。问题是,JOptionPane 关闭时会清除对话框。如果您真的想要显示两次,则必须阻止它。这是一个示例(但对我来说这是一个 hack):

import static java.util.concurrent.TimeUnit.SECONDS;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

public class DialogOnTimeoutCloser extends JFrame
{
   DialogOnTimeoutCloser()
   {
      super( "JOptionPane programmatic visibillity test." );

      SwingUtilities.invokeLater(() -> {

         getContentPane().setLayout( new FlowLayout() );
         setPreferredSize( new Dimension( 300, 300 ));
         setLocationRelativeTo(null);
         setDefaultCloseOperation(EXIT_ON_CLOSE);
         pack();
         setVisible(true);

         JOptionPane.showConfirmDialog( this, "Eggs are not green!", "True Statement", JOptionPane.YES_NO_CANCEL_OPTION );
      });
   }

   private void closeAllDialogs()
   {
      for (Window win : getOwnedWindows())
      {
          WindowListener[] ls = win.getWindowListeners();
          win.removeWindowListener(ls[0]);
          win.addWindowListener(new WindowAdapter() {
            
            @Override
            public void windowClosing(WindowEvent e) {
                ls[0].windowClosing(e);
                
            }
            
            @Override
            public void windowClosed(WindowEvent e) {
                // prevent clear window on close
                
            }
        });
         win.setVisible(false);
      }
   }

   private void openAllDialogs()
   {
      for (Window win : getOwnedWindows())
      {
         win.setVisible(true);
      }
   }

   public static void main(String[] args) throws InterruptedException
   {
      DialogOnTimeoutCloser dialogOnTimeoutCloser = new DialogOnTimeoutCloser();
      Thread.sleep(SECONDS.toMillis( 5 ));
      dialogOnTimeoutCloser.closeAllDialogs();
      Thread.sleep(SECONDS.toMillis( 5 ));
      dialogOnTimeoutCloser.openAllDialogs();
   }
}

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 2014-12-29
    相关资源
    最近更新 更多