Почему JDialog не отображается должным образом

Я создал метод для отображения сообщения в диалоговом окне, но размер диалогового окна меняется каждый раз, когда я запускаю свое приложение Java Swing. Ниже приведена ссылка на снимок экрана dailog:

Улучшение отображения окна сообщений
Правильное отображение окна сообщений

Ниже приведен метод (SetMSGDialog), который я создал для отображения JDialog.

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.


person Abhishek    schedule 11.07.2015    source источник
comment
1) избавиться от setSize(...), setBounds(...) и им подобных. 2) использовать менеджеры компоновки, чтобы помочь размеру и расположению компонентов. 3) запаковать перед отображением диалога. 4) не перегружайте свою программу.   -  person Hovercraft Full Of Eels    schedule 11.07.2015
comment
Кстати - Ubuntu, Eclipse, Linux?? Нет необходимости сообщать нам вашу ОС и IDE, если код не дает сбой только в этих конкретных условиях! И поверьте мне, этот код потерпит неудачу в любой системе, использующей любую IDE.   -  person Andrew Thompson    schedule 11.07.2015


Ответы (2)


Вы спрашиваете, почему ваш JDialog не отображается должным образом, и основная причина в том, что ваш код игнорирует менеджеры компоновки, которые уже используют ваши компоненты. Быстрое и ужасное решение — использовать абсолютный или null макет, но это не рекомендуется для размещения компонентов, поскольку это делает очень негибкие графические интерфейсы, которые, хотя они могут хорошо выглядеть на одной платформе и разрешении экрана, на большинстве других платформ выглядят ужасно. или разрешения экрана, и их очень сложно обновлять и поддерживать.

Предложения:

  • Избавьтесь от setSize(...), setBounds(...) и тому подобного.
  • Используйте менеджеры компоновки, чтобы определить размер и положение компонентов.
  • Pack перед отображением диалога.
  • Не злоупотребляйте модификатором static в своей программе.
  • Вы можете сделать что-то вроде приведенного ниже кода, но, показав это, 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();
         }
      });
   }
}
person Hovercraft Full Of Eels    schedule 11.07.2015

Вы пытались удалить MSGDialog.setSize(400,125); и позволить Swing определить размер?

person Sweder Schellens    schedule 11.07.2015
comment
Да, я пробовал это, но диалоговое окно очень маленькое, что трудно увидеть - person Abhishek; 11.07.2015
comment
Пробовали звонить pack()перед звонком MSGDialog.setVisible(true)? - person Sweder Schellens; 11.07.2015
comment
Проблема здесь в том, что ОП уже «выстрелил себе в ногу», не используя макеты. Когда мы вызываем pack(), обычно размер фрейма уменьшается до размера, необходимого для отображения компонентов, но поскольку макет null, контейнер не может вычислить предпочтительный или минимальный размер и возвращает 0x0 для обоих. Решение, конечно, состоит в том, чтобы использовать макеты (и отступы/границы для пробелов) для добавления компонентов, затем использовать pack() и setVisible(true) .. - person Andrew Thompson; 11.07.2015