Добавление JPanel из другого класса в JPanel в JFrame

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

JFrameTest.java:

package jframetest;

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class JFrameTest extends JFrame {

    public JFrameTest() {

        FlowLayout mainLayout = new FlowLayout();
        setSize(320, 480);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(mainLayout);

        JPanel panelMain = new JPanel(mainLayout);

        JButton testButton = new JButton("Test12");
        panelMain.add(testButton);

        JPanelOne panel = new JPanelOne();
        panelMain.add(panel);
        panel.setVisible(true);
        add(panelMain);



    }

    public static void main(String[] arguments) {

        JFrameTest frame = new JFrameTest();
        frame.setVisible(true);


    }
}

JPanelOne.java:

package jframetest;

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JPanel;


public class JPanelOne extends JPanel {

    public JPanelOne() {

        FlowLayout layoutPanel = new FlowLayout();
        JPanel panel = new JPanel(layoutPanel);
        JButton button = new JButton("test");
        panel.add(button);
        panel.setVisible(true);

    }

}

это хорошая практика, чтобы держать различные JPanels в своих собственных классах? (Пример: желая, чтобы JFrame содержал несколько JPanels одинакового размера, которые будут переключены путем установки setVisible () в true / false)

редактировать

Спасибо за все ваши ответы. Отмеченный. Теперь вернемся к моему вопросу:--4-->

Теперь, когда я знаю, как добавить отдельные элементы GUI, созданные в других классах, я хочу знать, можно ли организовать элементы с менеджером макетов в одном из классов (возможно, в каком-то другом контейнере, чем JPanel), поэтому я могу добавить их как группу, организованную в макете (вот почему я спрашивал о создании всей JPanel в другом классе). Как на изображение:

JPanel (этот 2-й класс) код для этого примера будет:

package jframetest;

import java.awt.*;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import net.miginfocom.swing.MigLayout;


public class JPanelOne extends JPanel {

    private JPanel panelSettingsMain;
    private JLabel labelChooseLanguage, labelWordsCollection;
    private JButton buttonSelectLanguage, buttonSelectCollection,
            buttonStatistics, buttonPrintingOptions, buttonAddNewWordCollection,
            buttonInterfaceCustomization;
    private JSeparator separatorSettingsOne, separatorSettingsTwo,
            separatorSettingsThree, separatorSettingsFour,
            separatorSettingsFive;
    private Color greenRegular, separatorGreenLight, separatorGreenDark;

    public JPanelOne() {

        // creating settings main panel

        // setting up layout managers
        MigLayout layoutSettingsMain = new MigLayout(
                "insets 3 0 0 0");

        // setting up colors
        greenRegular = new Color(30, 165, 145);
        separatorGreenLight = new Color(190, 240, 220);
        separatorGreenDark = new Color(130, 205, 180);

        panelSettingsMain = new JPanel(layoutSettingsMain);
        panelSettingsMain.setBackground(Color.WHITE);

            // setting up choose language label
            labelChooseLanguage = new JLabel("Choose language:");
            panelSettingsMain.add(labelChooseLanguage,
                    "gapleft 10, gaptop 15, width 200");

            // setting up select language button
            buttonSelectLanguage = new JButton("language");
            buttonSelectLanguage.setForeground(greenRegular);
            buttonSelectLanguage.setFocusPainted(false);
            buttonSelectLanguage.setBorder(null);
            buttonSelectLanguage.setContentAreaFilled(false);
            buttonSelectLanguage.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonSelectLanguage, "gapbottom 15px, wrap");

            // setting up light separator
            separatorSettingsOne = new JSeparator();
            separatorSettingsOne.setForeground(separatorGreenLight);
            panelSettingsMain.add(separatorSettingsOne,
                    "span 2, width 320, gapbottom 15, wrap");

            // setting up words collection label
            labelWordsCollection = new JLabel("Words collection:");
            panelSettingsMain.add(labelWordsCollection, "gapleft 10");

            // setting up selectcollection button
            buttonSelectCollection = new JButton("collection");
            buttonSelectCollection.setForeground(greenRegular);
            buttonSelectCollection.setFocusPainted(false);
            buttonSelectCollection.setBorder(null);
            buttonSelectCollection.setContentAreaFilled(false);
            buttonSelectCollection.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonSelectCollection,
                    "gapbottom 15px, wrap");

            // setting up dark separator
            separatorSettingsTwo = new JSeparator();
            separatorSettingsTwo.setForeground(separatorGreenDark);
            panelSettingsMain.add(separatorSettingsTwo,
                    "span 2, width 320, gapbottom 15px, wrap");

            // setting up show statistics button
            buttonStatistics = new JButton("Show statistics");
            buttonStatistics.setForeground(greenRegular);
            buttonStatistics.setFocusPainted(false);
            buttonStatistics.setBorder(null);
            buttonStatistics.setContentAreaFilled(false);
            buttonStatistics.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonStatistics,
                    "gapleft 10, gapbottom 15px, , wrap");

            // setting up dark separator
            separatorSettingsThree = new JSeparator();
            separatorSettingsThree.setForeground(separatorGreenDark);
            panelSettingsMain.add(separatorSettingsThree,
                    "span 2, width 320, gapbottom 15px, wrap");

            // setting up printing options button
            buttonPrintingOptions = new JButton("Printing options");
            buttonPrintingOptions.setForeground(greenRegular);
            buttonPrintingOptions.setFocusPainted(false);
            buttonPrintingOptions.setBorder(null);
            buttonPrintingOptions.setContentAreaFilled(false);
            buttonPrintingOptions.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonPrintingOptions,
                    "gapleft 10, gapbottom 15px, wrap");

            // setting up dark separator
            separatorSettingsFour = new JSeparator();
            separatorSettingsFour.setForeground(separatorGreenDark);
            panelSettingsMain.add(separatorSettingsFour,
                    "span 2, width 320, gapbottom 15px, wrap");

            // setting up add new word collection button
            buttonAddNewWordCollection = new JButton("Add new word collection");
            buttonAddNewWordCollection.setForeground(greenRegular);
            buttonAddNewWordCollection.setFocusPainted(false);
            buttonAddNewWordCollection.setBorder(null);
            buttonAddNewWordCollection.setContentAreaFilled(false);
            buttonAddNewWordCollection.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonAddNewWordCollection,
                    "gapleft 10, gapbottom 15px, , wrap");

            // setting up dark separator
            separatorSettingsFive = new JSeparator();
            separatorSettingsFive.setForeground(separatorGreenDark);
            panelSettingsMain.add(separatorSettingsFive,
                    "span 2, width 320, gapbottom 10px, wrap");

            // setting up interface customization button
            buttonInterfaceCustomization = new JButton(
                    "Interface customization");
            buttonInterfaceCustomization.setForeground(greenRegular);
            buttonInterfaceCustomization.setFocusPainted(false);
            buttonInterfaceCustomization.setBorder(null);
            buttonInterfaceCustomization.setContentAreaFilled(false);
            buttonInterfaceCustomization.setCursor(new java.awt.Cursor(
                    java.awt.Cursor.HAND_CURSOR));
            panelSettingsMain.add(buttonInterfaceCustomization,
                    "gapleft 10, gapbottom 15px, wrap");

    }

}

Я думал о навигации по GUI программы, установив JPanels (например, в Примере) видимым или не видимым.

  1. это хороший способ сделать это?
  2. должен ли я разделить свой GUI на несколько классов, или я должен держать все в одном? Я спрашиваю, потому что теперь только с половиной GUI в коде его около 400 строк долго (и он не может ничего сделать, кроме как просто "посмотреть" на этот момент). Как я уже говорил раньше - я новичок и его одно из самых длинных приложений, которые я написал до сих пор (что я уверен, что это не так долго!).

редактировать

может быть, я слишком много думаю, поэтому, в конце концов, нормально иметь большие классы GUI и контролировать видимость различных областей GUI, устанавливая их видимыми или нет?

редактировать

Я посмотрел в учебник CardLayout в Oracle, и похоже, что это хорошо для моей задачи (исключая создание JPanels из внешних классов, но это нормально). Сначала я неправильно понял это и думал о CardLayout только с точки зрения панели с вкладками (которую я не хотел реализовывать в своем проекте).

4 ответов


сначала, чтобы ответить на ваш вопрос, вам нужно добавить экземпляр вашей панели в кадр с чем-то вроде этого в вашем конструкторе JFrameTest:

add(new JPanelOne());

вы также должны добавить кнопку прямо в JPanelOne себя:

public class JPanelOne extends JPanel {   

  public JPanelOne() {   
    JButton button = new JButton("test");   
    add(button);   
  }   
}

во-вторых, я считаю, что есть проблема с этими строками кода:

    FlowLayout mainLayout = new FlowLayout(); 
    // snip...
    setLayout(mainLayout); 

    JPanel panelMain = new JPanel(mainLayout); 

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

setLayout(new FlowLayout());
JPanel panelMain = new JPanel(mainLayout);

С некоторой помощью (пользователь "Hilek" с другого сайта) я menaged получить jpanel из другого класса, чтобы быть displeyed в основной класс. Вот код:

JFrameTest.java:

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameTest extends JFrame {

        private JButton testButton;
        private JPanel panelMain;
        private JPanelOne panel;

        public JFrameTest() {

                // setting up JFrame
                setLayout(null);
                setPreferredSize(new Dimension(420, 90));
                setResizable(false);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                // creating main JPanel (white)
                panelMain = new JPanel();
                panelMain.setBackground(Color.WHITE);
                panelMain.setBounds(0, 0, 420, 90);
                panelMain.setPreferredSize(new Dimension(200, 40));
                add(panelMain);

                // creating JButton in the main JPanel (white)
                testButton = new JButton("Button from main class");
                panelMain.add(testButton);

                // creating new JPanelOne object from JPanelOne class containing black JPanel
                panel = new JPanelOne();

                // adding black JPanel to main JPanel (white)
                panelMain.add(panel);

                pack();

        }

        public static void main(String[] arguments) {

                // creating JFrame object and setting it visible
                JFrameTest frame = new JFrameTest();
                frame.setVisible(true);

        }

}

JPanelOne.java:

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.SwingConstants;

public class JPanelOne extends JPanel
{

        public JPanelOne()
        {
                // setting up black JPanel
                JPanel panel = new JPanel();
                panel.setPreferredSize(new Dimension(220, 40));
                panel.setBackground(Color.BLACK);

                // creating button on external JPanel
                JButton button = new JButton("Button (+JPanel) from external class");

                // adding button to the black JPanel
                panel.add(button);

                // adding blackJPanel
                add(panel);
        }
}

экран печати рабочего примера:

http://i.stack.imgur.com/qKeBp.jpg

возможно, кто-то найдет это полезным в своей проблеме.


проблема исходит от JPanelOne класса. Он наследует JPanel но в конструкторе, вы создаете новый JPanel и затем вы добавляете к нему кнопку. Если вы сделаете это вместо этого:

public class JPanelOne extends JPanel {

   public JPanelOne() {
       JButton button = new JButton("test");
       add(button);
   }
}

он должен работать, как вы ожидаете.


не называй setSize() на вашем JFrame. Вместо этого пусть макеты устанавливают правильные размеры своих компонентов и графического интерфейса. После добавления всех компонентов в GUI, вызовите pack() на JFrame, затем вызовите setVisble(true). Обратите внимание, что большинство макетов уважают preferredSize компонента больше, чем его размер.

кроме того, ваш вызов setVisible(true)на ваших отдельных компонентах нет необходимости (если вы не меняете их видимость после того, как GUI по какой-либо причине запущен). Вы также захотите подробнее об использовании менеджеров макетов и, вероятно, будет использовать FlowLayout меньше, как только вы изучили их.

редактировать
Относительно вашего недавнего редактирования:

может быть, я слишком много думаю, поэтому, в конце концов, нормально иметь большие классы GUI и контролировать видимость различных областей GUI, устанавливая их видимыми или нет?

Я отвечу, что иногда это полезно, например, если вы хотите изменить стандартный калькулятор в научный калькулятор, иногда хорошо просто показать уже созданную JPanel, заполненную кнопками предварительного расчета, используя setVisible (true). Если, с другой стороны, вы хотите поменять "представления" вашего GUI, чтобы отразить существенное изменение его состояния, например, текстовый процессор, переходящий из режима редактирования в режим печати, вы можете легко поменять JPanels, чтобы сделать это с помощью CardLayout.