【问题标题】:Why JDialog not displaing properly为什么对话框不能正确显示
【发布时间】:2015-07-11 12:58:03
【问题描述】:

我已经创建了一种在对话框中显示消息的方法,但是每次运行我的 java swing 应用程序时对话框的大小都会发生变化,下面是 dailog 屏幕截图的链接:

Improrer Message Box Display
Proper Message Box Display

下面是我为 JDialog Display 创建的方法(SetMSGDialog)

public class DemoClass
{
    private static JDialog MSGDialog;
    private static JPanel MSGPanel;
    private static JLabel MSGLabel;
    private static JButton MSGButton;

    DemoClass()
    {
        MSGDialog = new JDialog(MSGDialog,"Message",JDialog.ModalityType.APPLICATION_MODAL);
        MSGPanel = new JPanel(null);
        MSGLabel = new JLabel();
        MSGButton = new JButton("Close");
    }

    public static void SetMSGDialog(String MSG)
    {
        MSGDialog.setModal(true);
        MSGDialog.setSize(400,125);
        MSGDialog.setResizable(false);
        MSGDialog.setLocationRelativeTo(null);
        MSGLabel.setText(MSG);
        MSGButton.setText("Close");
        MSGLabel.setBounds(25, 25, 375, 30);
        MSGButton.setBounds(160,70,80,30);
        MSGPanel.add(MSGLabel);
        MSGPanel.add(MSGButton);
        MSGDialog.add(MSGPanel);
        MSGDialog.setVisible(true);
    }

    public static void main(String[] args)
    {
        DemoClass MsgBox = new DemoClass();
        MsgBox.SetMSGDialog("Please Login First");
    }
}

请告诉我我做错了什么。我必须做什么才能正确显示 Jdialog。

【问题讨论】:

  • 1) 摆脱setSize(...)setBounds(...)等。 2) 使用布局管理器来帮助调整组件的大小和位置。 3)在显示对话框之前打包。 4) 不要过度静态化你的程序。
  • 顺便说一句-Ubuntu、Eclipse、Linux??无需告诉我们您的操作系统和 IDE,除非代码仅在这些特定条件下失败!相信我,这段代码在任何系统上都会失败,使用任何 IDE。

标签: java swing layout-manager null-layout-manager


【解决方案1】:

你问为什么你的 JDialog 没有正确显示,主要原因是你的代码忽略了你的组件已经使用的布局管理器。一个快速而糟糕的解决方案是使用绝对布局或null 布局,但不建议将其用于组件放置,因为这会导致非常不灵活的 GUI,虽然它们在单一平台和屏幕分辨率上可能看起来不错,但在大多数情况下它们看起来很糟糕其他平台或屏幕分辨率,并且很难更新和维护。

建议:

  • 摆脱 setSize(...)、setBounds(...) 等。
  • 使用布局管理器来帮助调整组件的大小和位置。
  • 在显示对话框之前打包。
  • 不要在程序中过度使用静态修饰符。
  • 您可以执行类似下面的代码的操作,但在展示了这一点后,JOptionPane 将是显示此类消息的最简单方法。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class DemoClass2 extends JPanel {
   // constants
   private static final String TITLE = "Message";
   private static final float LABEL_POINTS = 24f;
   private static final int L_GAP = 15;
   private static final int B_GAP = 25;

   // static poor man's singlton instance
   private static DemoClass2 demoClass2;
   private JDialog dialog = new JDialog();
   private JLabel label = new JLabel("", SwingConstants.CENTER);

   public DemoClass2() {
      dialog.setModal(true);
      dialog.setTitle(TITLE);

      label.setFont(label.getFont().deriveFont(Font.BOLD, LABEL_POINTS));
      label.setBorder(BorderFactory.createEmptyBorder(L_GAP, L_GAP, L_GAP, L_GAP));

      JPanel btnPanel = new JPanel(new GridBagLayout());
      btnPanel.setBorder(BorderFactory.createEmptyBorder(B_GAP, B_GAP, B_GAP, B_GAP));
      btnPanel.add(new JButton(new DisposeAction("Close", KeyEvent.VK_C)));

      setLayout(new BorderLayout());
      //setBorder(border);
      add(label, BorderLayout.PAGE_START);
      add(btnPanel, BorderLayout.CENTER);

      dialog.getContentPane().add(this);
   }

   private void setMessage(String message) {
      label.setText(message);
   }

   private void display() {
      dialog.setResizable(false);
      dialog.pack();
      dialog.setLocationRelativeTo(null);
      dialog.setVisible(true);
   }

   public void setMessageAndDisplay(String message) {
      setMessage(message);
      display();
   }

   public static void displayMessage(String message) {
      if (demoClass2 == null) {
         demoClass2 = new DemoClass2();
      }
      demoClass2.setMessageAndDisplay(message);
   }

   private class DisposeAction extends AbstractAction {
      public DisposeAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         Component c = (Component) e.getSource();
         if (c == null) {
            return;
         }
         Window win = SwingUtilities.getWindowAncestor(c);
         if (win == null) {
            return;
         }
         win.dispose();         
      }
   }

   private static void createAndShowGui() {
      DemoClass2.displayMessage("Fubars Rule!!!");

      DemoClass2.displayMessage("This is a bit of a longer message. The dialog should get bigger.");
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

【讨论】:

    【解决方案2】:

    您是否尝试过删除 MSGDialog.setSize(400,125); 并让 Swing 决定大小?

    【讨论】:

    • 是的,我试过了,但是对话框很小,很难看到
    • 在调用MSGDialog.setVisible(true)之前尝试调用pack()
    • 这里的问题是 OP 已经通过不使用布局“在脚上开枪”。当我们调用pack() 时,通常它会将框架缩小到显示组件所需的大小,但由于布局为null,容器无法计算其首选或最小大小,并且两者都会返回 0x0 .当然,解决方案是使用布局(以及空白区域的填充/边框)来添加组件,然后使用pack()setVisible(true) ..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多