Я видел это здесь несколько раз, но в сообщениях, которые я видел, никто не объяснил это. Почему я не должен расширять JFrame (или любой компонент)? Существуют ли условия, в которых я должен распространять компонент, или это твердое правило, которого вы не делаете?
Почему вы не должны расширять JFrame и другие компоненты?
Ответ 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
Я знаю, что это старый пост, но я просто наткнулся на него, и я должен сказать вам... расширение ограничено моими способами вызова определенных действий объекта. Я на самом деле переписываю некоторые части кода, чтобы избавиться от поврежденного ущерба, вызвавшего меня. Если я не пишу однофайльную программу, я больше не буду использовать расширенные расширения.