Подтвердить что ты не робот

Почему вы не должны расширять JFrame и другие компоненты?

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

4b9b3361

Ответ 1

Вообще говоря, расширение компонента, как правило, выполняется строго для использования компонента. Это сильно ограничивает ваши варианты ненужными способами с точки зрения дизайна, так что ваши классы не могут распространять разные классы, вы не можете скрыть методы JFrame, что затрудняет его поддержку и проще запускать неожиданные ошибки при использовании класса.

Обычно намерение заключается в том, чтобы использовать класс для рисования кадра, а композиция предпочтительнее над наследованием.

При этом подкласс должен быть прекрасным, если вы намереваетесь, чтобы ваш подкласс добавлял функциональные возможности проекта к кадру (например, методы удобства и т.п.), где подкласс использовался вместо самого кадра, но использовался как в целом, а не как представление конкретного кадра в приложении.

Ответ 2

Предпочитают состав над наследованием. Все обычные причины. Состав заставляет меньше зависимостей между кодом.

Swing и события AWT, компоненты ужасно сложны. Ты не хочешь быть в этом беспорядке. Вы можете легко переопределить методы случайно. В тех случаях, когда вам необходимо переопределить методы, трудно понять, где это делается, если оно относится к нормальному коду.

Ответ 3

Если ваше приложение ДЕЙСТВИТЕЛЬНО просто JFrame, продолжайте и расширьте его. Однако лучше всего использовать композицию объекта, а не наследование, если вы просто используете JFrame.

Если ваш объект расширяет какой-либо другой объект, у вас не будет выбора в этом вопросе.

Ответ 4

Я не вижу проблемы до тех пор, пока вы расширяете класс и можете сохранить "is-a" аспекты наследования.

Когда вы расширяете JPanel, но ваш новый объект не является настоящей специализацией JPanel, вы попадаете в неприятности. Но если вы создадите новый SpeciallyFormattedJLabel, который расширяет JLabel, я не вижу проблем с этим.

Ответ 5

Есть (как говорят все остальные) множество проблем, которые могут возникнуть из-за расширения компонентов, таких как JFrames. Я столкнулся с этими проблемами, но опубликовал несколько примеров кода, которые я использовал для решения моих проблем.

У меня было много трудностей, чтобы сосредоточиться на конкретных JFrames, чтобы вытащить их на передний план. В моем решении используются классы, расширяющие JFrame и панель инструментов класса, которая реализует WindowListener.

Как это работает.

В принципе, существует класс Dash, который запускает класс Dashboard. Этот класс Dashboard создает классы ExtendedFrame для открытия нескольких кадров.

Затем вы можете привязать определенные кадры к фокусу, обратившись к рамкам ArrayList.

Я не уверен, почему он ошибается, когда вы храните вещи по-другому, но я считаю, что он должен что-то сделать с тем, что JFrames являются дочерними элементами окна. Когда JFrames создаются в отдельном классе (например, DashboardFrameManager), у них нет Dashboard в качестве родителя. Возможность получить фокус исчезла.

Попробуйте добавить прослушиватель клавиш к панели управления для доступа к JFrames, нажав клавишу (я также реализовал очередь для циклического перехода).

Имейте в виду, что я не включал импорт или остальные методы, необходимые для реализации WindowListener.

public class Dash {

      public static void main(String[] args) {
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                  Dashbored c = new Dashbored();

              }
          });
      }
}


public class Dashbored implements WindowListener {

    private static ArrayList<JFrame> frames;
    private JFrame frame;

    public Dashbored()
    {

        frame = new JFrame("go go gadget");
        frames = new ArrayList<JFrame>();
        frame.addWindowListener(this);
        addList( frame.getContentPane() );
        frame.setSize(300,300);
        frame.pack();
        frame.setVisible(true);

        simulateFramesOpening();
    }

    public static void addList(Container c)
    {
        c.setLayout(new GridBagLayout());

        JButton jbnButton;
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;

        jbnButton = new JButton("Button 1");
        gbc.weightx = 0.5;
        gbc.gridx = 0;
        gbc.gridy = 0;
        c.add(jbnButton, gbc);

        return;

    }

    public static void simulateFramesOpening()
    {
        //make 7 frames, with titles 1-7
        for(int i = 0; i < 7; i++)
        {
            //this is our extended frame class
            //which can create and populate a JFrame
            FrameExtended z = (new FrameExtended(i+1));
            //add the frame to our list of frames
            frames.add((JFrame) z.getFrame());
        }
        System.out.println("changing it!");
        //the # in the ArrayList of which JFrame to give focus (0-6)
        int frameToFocus = 4; // <-- arbitrary, gets JFrame with title "5"
        //both requestFocus and toFront work
        frames.get(frameToFocus).requestFocus();
        frames.get(frameToFocus).toFront();

    }   
}

public class FrameExtended extends JFrame{

    private JFrame j;

    public FrameExtended(int i)
    {
        j = new JFrame( ""+i+"" );
        j.setSize(375,500);
        j.setLocation(360+75*i, 150+50*i);
        //j.pack();
        j.setVisible(true);
    }

    public JFrame getFrame()
    {
        return j;
    }
}

Ответ 6

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