Вопрос по проектированию подходов на JDialogs в приложениях Swing - PullRequest
1 голос
/ 03 июля 2011

Обычно в приложении Swing, если я хочу отобразить JDialogs для пользователя, я создаю их один раз, а затем снова их использую.
Обычно основной JFrame имеет ссылки на эти JDialogs.
Иногда, хотя мне нужно отобразить JDialog из частей кода вне JFrame class.
Обычно я делаю переменные-члены JDialog (из JFrame) общедоступными, и они либо являются статическими, либо передают ссылку на массив JFrame, чтобы иметь возможность доступа к JDialog.
Это работает, но мне это кажется грязным.
Мне было интересно, есть ли стандартный подход к дизайну для чего-то вроде этого?

Ответы [ 2 ]

2 голосов
/ 03 июля 2011

Моя собственная философия заключается в том, чтобы сделать почти все поля приватными, включая диалог, и раскрывать только то, что нужно раскрыть, не больше и не меньше. Например, если у меня вызывается JDialog из другого класса, и я получаю информацию из этого диалога, я предоставляю только информацию через общедоступные методы получения, а не само диалоговое окно.

Редактировать 1
Извините за грубый перерасход и намного более длинный, чем ожидалось, код, но это своего рода то, что я имел в виду в виде MVC и создал очень быстро:

import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.*;

import javax.swing.*;

public class DialogEg {
   private static void createAndShowUI() {
      JFrame frame = new JFrame("Dialog Eg");

      MainPanel mainPanel = new MainPanel();
      MainControl mainControl = new MainControl(frame);
      mainControl.setMainPanel(mainPanel);
      mainPanel.setControl(mainControl);

      frame.getContentPane().add(mainPanel.getMainPanel());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

class MainPanel {
   private JPanel mainPanel = new JPanel();
   private JButton showDlgBtn = new JButton("Show Dialog");
   private JTextField field = new JTextField(10);
   private MainControl mainControl;

   public MainPanel() {
      mainPanel.add(showDlgBtn);
      mainPanel.add(field);
      field.setEditable(false);

      showDlgBtn.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            if (mainControl != null) {
               mainControl.showDialog();
            }
         }
      }); 
   }

   public void setControl(MainControl mainControl) {
      this.mainControl = mainControl;
   }

   public void setFieldText(String text) {
      field.setText(text);
   }

   public JPanel getMainPanel() {
      return mainPanel;
   }
}

class DialogPanel {
   private static final String[] COMBO_DATA = {"", "one", "two", "three", "four"};
   private JPanel dialogPanel = new JPanel();
   private JComboBox combo = new JComboBox(COMBO_DATA);

   public DialogPanel() {
      dialogPanel.add(combo);
      combo.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            Window window = SwingUtilities.getWindowAncestor(dialogPanel);
            window.dispose();
         }
      });
   }

   public JPanel getDialogPanel() {
      return dialogPanel;
   }

   public String getSelectedText() {
      return combo.getSelectedItem() == null ? "" : combo.getSelectedItem().toString();
   }
}

class MainControl {
   private DialogPanel dlgPanel = new DialogPanel();
   private MainPanel mainPanel;
   private JFrame frame;

   public MainControl(JFrame frame) {
      this.frame = frame;
   }

   public void setMainPanel(MainPanel mainPanel) {
      this.mainPanel = mainPanel;
   }

   public void showDialog() {
      if (mainPanel != null) {
         JDialog dialog = new JDialog(frame, "Dialog", ModalityType.APPLICATION_MODAL);
         dialog.getContentPane().add(dlgPanel.getDialogPanel());
         dialog.pack();
         dialog.setLocationRelativeTo(null);
         dialog.setVisible(true);

         String text = dlgPanel.getSelectedText();
         if (text != null) {
            mainPanel.setFieldText(text);
         }
      }
   }

}

Ключевым моментом здесь является то, что MainPanel не знает о DialogPanel и наоборот, так как все это связано с MainControl через чудеса MVC.

2 голосов
/ 03 июля 2011

Либо передайте экземпляр JFrame вспомогательным классам, которые создают новые экземпляры JDialog, либо, если ваше приложение имеет один кадр, сделайте этот кадр доступным из любого места:

public class MyApp {

    private static JFrame mainFrame;

    public static JFrame getMainFrame() {
        return MyApp.mainFrame;
    }

    public static void main(String[] args) {
        // ...
        MyApp.mainFrame = new JFrame();
        // ...
    }
}

Я обычно избегаю повторного использования экземпляров диалогов: это делает код более трудным для написания (вам нужно позаботиться о предыдущем состоянии диалогового окна), и он потребляет память для хранения невидимых экземпляров диалогов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...