2

I am trying to get some Java skills back because i worked for a long time in webdevelopment. Now I am just create a main Jframe where are a little Menu and a Class createSchueler extends JPanel.

So what I want to do if you go into the Menu click Neu > Schueler

A new Jpanel should be created and added to the Window

Main Class

public class MainWindow {

private JFrame frame;


/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainWindow window = new MainWindow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public MainWindow() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 807, 541);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    JPanel createSchueler = new createSchueler();

    JMenuBar menuBar = new JMenuBar();
    frame.setJMenuBar(menuBar);

    JMenu mnNewMenu = new JMenu("Neu");
    mnNewMenu.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            createSchueler.setVisible(true);
            frame.getContentPane().add(createSchueler);

        }
    });
    menuBar.add(mnNewMenu);

    JMenuItem mntmSchler = new JMenuItem("Sch\u00FCler");
    mnNewMenu.add(mntmSchler);

    JMenu mnBearbeiten = new JMenu("Bearbeiten");
    menuBar.add(mnBearbeiten);

    JMenuItem mntmSchler_1 = new JMenuItem("Sch\u00FCler");
    mnBearbeiten.add(mntmSchler_1);


  }
}

The createSchueler Class extends JPanel that i want to add to the frame

public class createSchueler extends JPanel {
private JTextField textField;
private JTextField textField_1;
private JTextField textField_2;

/**
 * Create the panel.
 */
public createSchueler() {
    setLayout(null);

    JLabel lblNeuenSchuelerErstellen = new JLabel("Neuen Schueler erstellen");
    lblNeuenSchuelerErstellen.setFont(new Font("Tahoma", Font.PLAIN, 22));
    lblNeuenSchuelerErstellen.setBounds(29, 27, 268, 27);
    add(lblNeuenSchuelerErstellen);

    JLabel lblVorname = new JLabel("Vorname");
    lblVorname.setBounds(29, 102, 46, 14);
    add(lblVorname);

    textField = new JTextField();
    textField.setBounds(97, 99, 172, 20);
    add(textField);
    textField.setColumns(10);

    JLabel lblNachname = new JLabel("Nachname");
    lblNachname.setBounds(29, 133, 69, 14);
    add(lblNachname);

    textField_1 = new JTextField();
    textField_1.setBounds(97, 130, 172, 20);
    add(textField_1);
    textField_1.setColumns(10);

    JLabel lblGeburtstag = new JLabel("Geburtstag");
    lblGeburtstag.setBounds(29, 169, 69, 14);
    add(lblGeburtstag);

    textField_2 = new JTextField();
    textField_2.setBounds(97, 166, 172, 20);
    add(textField_2);
    textField_2.setColumns(10);

    ButtonGroup bg = new ButtonGroup();

    JRadioButton rdbtnMnnlich = new JRadioButton("M\u00E4nnlich");
    rdbtnMnnlich.setBounds(29, 206, 69, 23);
    bg.add(rdbtnMnnlich);

    JRadioButton rdbtnWeiblich = new JRadioButton("Weiblich");
    rdbtnWeiblich.setBounds(97, 206, 109, 23);
    bg.add(rdbtnWeiblich);



   }
 }

Everything is important hopefully :D

Ogre Codes
  • 18,693
  • 1
  • 17
  • 24

1 Answers1

4

Use a CardLayout to swap JPanels rather than adding them by hand. If you must add them by hand, be sure that the receiving container's layout manager is up to the task and handles the addition well. For example BorderLayout would take it fine, but GroupLayout won't. If you do add or remove by hand, call revalidate(); and repaint() on the container after these changes.

Also you're using null layout in your added JPanel and contentPane which will completely ruin it's preferredSize calculation. Never use this layout. Learn to use and then use the layout managers. This is your main mistake.

For more on this, please read: Why is it frowned upon to use a null layout in Swing?

For example:

import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class MainGui {
    public static final String SCHUELER_PANEL = "Schueler Panel";
    public static final String EMPTY = "Empty Panel";
    private JPanel mainPanel = new JPanel();
    private JMenuBar menuBar = new JMenuBar();
    private CardLayout cardLayout = new CardLayout();
    private SchuelerPanel schuelerPanel = new SchuelerPanel();


    public MainGui() {
        mainPanel.setLayout(cardLayout);
        mainPanel.add(new JLabel(), EMPTY); // empty label
        mainPanel.add(schuelerPanel, SCHUELER_PANEL);

        JMenu menu = new JMenu("Panel");
        menu.add(new JMenuItem(new SwapPanelAction(EMPTY)));
        menu.add(new JMenuItem(new SwapPanelAction(SCHUELER_PANEL)));
        menuBar.add(menu);
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

    public JMenuBar getMenuBar() {
        return menuBar;
    }

    @SuppressWarnings("serial")
    private class SwapPanelAction extends AbstractAction {
        public SwapPanelAction(String title) {
            super(title);
            int mnemonic = (int) title.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            cardLayout.show(mainPanel, (String) getValue(NAME));
        }
    }

    private static void createAndShowGui() {
        MainGui mainGui = new MainGui();
        JFrame frame = new JFrame("Main Gui");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainGui.getMainPanel());
        frame.setJMenuBar(mainGui.getMenuBar());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

and

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class SchuelerPanel extends JPanel {
    private static final String TITLE_TEXT = "Lorem Ipsum Dolor Sit Amet";
    public static final String[] LABEL_STRINGS = {"Monday", "Tuesday", "Wednesday"};
    private Map<String, JTextField> labelFieldMap = new HashMap<>();

    public SchuelerPanel() {
        JLabel titleLabel = new JLabel(TITLE_TEXT, JLabel.CENTER);
        titleLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20));

        JPanel labelFieldPanel = new JPanel(new GridBagLayout());
        for (int i = 0; i < LABEL_STRINGS.length; i++) {
            addToPanel(labelFieldPanel, LABEL_STRINGS[i], i);
        }

        // Don't do what I'm doing here: avoid "magic" numbers!
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
        setLayout(new BorderLayout(10, 10));
        add(titleLabel, BorderLayout.PAGE_START);
        add(labelFieldPanel, BorderLayout.CENTER);
    }

    // get the text from the JTextField based on the JLabel associated with it
    public String getText(String labelText) {
        JTextField textField = labelFieldMap.get(labelText);
        if (textField == null) {
            throw new IllegalArgumentException("For labelText: " + labelText);
        }
        return textField.getText();
    }

    private void addToPanel(JPanel gblUsingPanel, String labelString, int row) {
        JLabel label = new JLabel(labelString);
        label.setFont(label.getFont().deriveFont(Font.BOLD));
        JTextField textField = new JTextField(10);
        labelFieldMap.put(labelString, textField);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = row;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.insets = new Insets(5, 5, 5, 5);
        gblUsingPanel.add(label, gbc);

        gbc.gridx = 1;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gblUsingPanel.add(textField, gbc);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("SchuelerPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SchuelerPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Ok i heared about the null layout some bad things too. But i just used it because its an simple example, but i will remind this in the future. But i still dont know why my frame isnt displaying the Jpanel, i am searching the error in my code you have any idea ? It isnt working with repaint or revalidate :( – KungFuKugelfisch Aug 22 '16 at 20:25
  • @KungFuKugelfisch: I already told you why -- you're using null layouts. If you'd use appropriate layouts, the problem will go away. – Hovercraft Full Of Eels Aug 22 '16 at 20:45
  • 2
    @KungFuKugelfisch: Your JPanel has a preferred size of 0,0 because of use of null layouts, and because you're using null layouts in the contentPane it won't even respect the preferred size but rather the actual size, neither of which have been set. Again, just use layout managers. Bite the bullet and learn them. – Hovercraft Full Of Eels Aug 22 '16 at 20:46
  • ah ok thank now i got. i thought the layout doesnt matter and the null layout would be a general tip. Thank you for the quik answer now it makes sense – KungFuKugelfisch Aug 22 '16 at 21:05
  • @KungFuKugelfisch: please see example code to show CardLayout and layout managers at work – Hovercraft Full Of Eels Aug 22 '16 at 21:32