Układanie elementów w prostym GUI

0

Witam. Pracuję nad gui, w którym jest pozagnieżdżanych kilka frame'ów/labelów/listenerów. Jedno z okien wygląda tak: na górze umieszczony jest JMenu "Zmień listę", następnie w nim są wypisane kolejne kategorie prowadzących/grup/sal, itd. Kliknięcie którejś z listy powoduje pojawienie się JLista z dostępnymi buttonami – listSelectionListener umożliwia nam wejście w konkretną rubrykę naszej listy, celem zobaczenia szczegółów. Wszystko działa jak należy, poza samym rozmieszczeniem obiektów – menu wyświetla się z lewej strony i przykrywa naszą listę (dlaczego z lewej? Nie mam pojęcia. Powinno u samej góry). Lista natomiast uaktywnia się dopiero po zabawą kursorem i rozdzielczością – wcześniej jest przykryta przez JMenu. Powiem szczerze, że nie mam żadnego doświadczenia w rozmieszczaniu tych wszystkich obiektów. Prosiłbym o pomoc lub małą podpowiedź. Poniżej zamieszczam kod. Celem jest, aby nasze menu było na górze i w zależności od wybranej pozycji, pojawiała się lista typowa dla danej kategorii, gdzie po kliknięciu w daną kategorię pojawią się odpowiednie dla niej obiekty (np. wybór konkretnego prowadzącego i jego dane personalne).

public class wprowadzDane extends JFrame implements ActionListener {

    JFrame JFwprowadzDane = new JFrame("Wprowadź dane");
    JMenuItem JMIwyswietlProwadzacych;
    JMenuItem JMIwyswietlGrupy;
    JMenuItem JMIwyswietlSale;
    JMenuItem JMIwyswietlZajecia;
    JMenuItem JMIwyjscie;
    JList<wyswietlProwadzacych> JLprowadzacy = new JList<>();
    DefaultListModel<wyswietlProwadzacych> model = new DefaultListModel<>();

    public wprowadzDane() {

        JFwprowadzDane.setVisible(true);
        JFwprowadzDane.setSize(600, 400);
        JFwprowadzDane.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // główne menu
        JMenuBar JMBARwprowadzDane = new JMenuBar();
        JFwprowadzDane.setJMenuBar(JMBARwprowadzDane);

        // kategorie menu

        JMenu JMpodgladDanych = new JMenu("Zmień listę");
        JMBARwprowadzDane.add(JMpodgladDanych);

        // obiekty podkategorii

        JMIwyswietlProwadzacych = new JMenuItem("Prowadzący");
        JMIwyswietlGrupy = new JMenuItem("Grupy");
        JMIwyswietlSale = new JMenuItem("Sale");
        JMIwyswietlZajecia = new JMenuItem("Zajęcia");
        JMIwyjscie = new JMenuItem ("Wyjście");

        // dodawanie obiektów do podkategorii

        JMpodgladDanych.add(JMIwyswietlProwadzacych);
        JMpodgladDanych.add(JMIwyswietlGrupy);
        JMpodgladDanych.add(JMIwyswietlSale);
        JMpodgladDanych.add(JMIwyswietlZajecia);
        JMpodgladDanych.addSeparator();
        JMpodgladDanych.add(JMIwyjscie);

        // dodawanie do actionListenerów

        JFwprowadzDane.add(JMBARwprowadzDane);
        JMIwyswietlProwadzacych.addActionListener(this);
        JMIwyjscie.addActionListener(this);
        JMIwyjscie.setAccelerator(KeyStroke.getKeyStroke("ctrl X"));

        // lista prowadzących, ustawienia
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object Zrodlo = e.getSource();

        if (Zrodlo == JMIwyswietlProwadzacych) {
            JLprowadzacy.setModel(model);

            JLabel JLBprowadzacy = new JLabel();
            JPanel JPprowadzacy = new JPanel();
            JSplitPane JSprowadzacy = new JSplitPane();
            JSprowadzacy.setSize(600,200);
            JSprowadzacy.setVisible(true);

            JSprowadzacy.setLeftComponent(new JScrollPane(JLprowadzacy));
            JPprowadzacy.add(JLBprowadzacy);
            JSprowadzacy.setRightComponent(JPprowadzacy);

            model.addElement(new wyswietlProwadzacych(1, "Robert", "Kowalski"));
            model.addElement(new wyswietlProwadzacych(2, "Robert", "Kubicki"));

            JLprowadzacy.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    wyswietlProwadzacych WP = JLprowadzacy.getSelectedValue();
                    JLBprowadzacy.setText("Indeks: " + WP.id + "\nImię: " + WP.imie + "\nNazwisko: " +  WP.nazwisko);
                }
            });

            JFwprowadzDane.add(JSprowadzacy);
        }

        if (Zrodlo == JMIwyjscie) {
           JFwprowadzDane.dispose();
        }
    }
0

Nie upychaj tego na siłę w jednej klasie. Zrób sobie osobną klasę rozszerzajacą menu, osobny jeden panel, osobny drugi panel itd. Nagle problemy same znikają ;)

0

W porządku :). Pozagnieżdżałem trochę klasy i wygląda to teraz tak:

wprowadzDane.java:

@Override
    public void actionPerformed(ActionEvent e) {
        Object Zrodlo = e.getSource();

        if (Zrodlo == JMIwyswietlProwadzacych) {
            JPanel JPprowadzacy = new JPanel();
            JPprowadzacy.add(new listaProwadzacych());
            JFwprowadzDane.add(JPprowadzacy);
        }

        if (Zrodlo == JMIwyjscie) {
           JFwprowadzDane.dispose();
        }
    }

listaProwadzacych.java:

package com.gui;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * Created by Marcin on 09.12.2016.
 */
public class listaProwadzacych extends JPanel implements ActionListener {

    JButton JBusun, JBdodaj, JBedytuj;
    JPanel JPwprowadzDane;
    JList<wyswietlProwadzacych> JLprowadzacy = new JList<>();
    DefaultListModel<wyswietlProwadzacych> model = new DefaultListModel<>();

    listaProwadzacych()
    {
        JPwprowadzDane = new JPanel();
        JPwprowadzDane.setBounds(30,30, 400,200);
        JPwprowadzDane.setVisible(true);

        JBdodaj = new JButton("Dodaj");
        JBdodaj.setBounds(300,300, 75, 20);
        JPwprowadzDane.add(JBdodaj);

        JBedytuj = new JButton("Edytuj");
        JBedytuj.setBounds(400,300, 75, 20);
        JPwprowadzDane.add(JBedytuj);

        JBusun = new JButton("Usuń");
        JBusun.setBounds(500,300, 75, 20);
        JPwprowadzDane.add(JBusun);

        JLprowadzacy.setModel(model);

        JLabel JLBprowadzacy = new JLabel();
        JPanel JPprowadzacy = new JPanel();
        JSplitPane JSprowadzacy = new JSplitPane();
        JSprowadzacy.setBounds(30,30, 300, 200);
        JSprowadzacy.setVisible(true);

        JSprowadzacy.setLeftComponent(new JScrollPane(JLprowadzacy));
        JPprowadzacy.add(JLBprowadzacy);
        JSprowadzacy.setRightComponent(JPprowadzacy);

        model.addElement(new wyswietlProwadzacych(1, "Robert", "Kowalski"));
        model.addElement(new wyswietlProwadzacych(2, "Robert", "Kubicki"));

        JLprowadzacy.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                wyswietlProwadzacych WP = JLprowadzacy.getSelectedValue();
                JLBprowadzacy.setText("Indeks: " + WP.id + "\nImię: " + WP.imie + "\nNazwisko: " +  WP.nazwisko);
            }
        });

       JPwprowadzDane.add(JSprowadzacy);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object Zrodlo = e.getSource();

        if (Zrodlo == JBusun)
        {
            //model.removeElementAt();
        }
    }
}

Co się zmieniło: menu dalej jest wyświetlane z boku (kod powyżej), natomiast lista przestała się wyświetlać. w klasie listaProwadzacych.java utworzyłem JPanel, który następnie powinien być dodany do okna naszej klasy poprzez wybranie opcji z JMenu, ale niestety nic się nie pojawia w naszym głównym Frame.

0

A jak dodajesz panel to robisz potem jakieś revalidate i repaint? Bo inaczej nie będzie widać. No i jaki layout manager tam ustawiasz?

0

Dodałem te dwie opcje, layout ustawiłem na null. Ogólnie widać, że JMenu ustawiło się poprawnie po wykonaniu opcji revalidate i repaint, ale lista nadal się nie wyświetla i jest schowana w konstruktorze. Ogólnie: JFrame wprowadźDane składa się z JMenu, gdzie po wybraniu którejś listy aktualizowany będzie cały JFrame przez konkretny JPanel – w tym wypadku skupiamy się na liście prowadzących. Konstruktor za każdym razem będzie się wyświetlał od nowa (nie ma co się przejmować danymi, bo będą aktualizowane w jeszcze innej klasie, te powyżej są przykładowe).

ActionListener po wybraniu prowadzącego wygląda tak:

if (Zrodlo == JMIwyswietlProwadzacych) {
            JPanel JPprowadzacy = new JPanel();
            JPprowadzacy.add(new listaProwadzacych());
            JFwprowadzDane.add(JPprowadzacy);
            JFwprowadzDane.revalidate();
            JFwprowadzDane.repaint();

Jednak lista nadal się nie wyświetla, chociaż w konstruktorze klasy jest dodana do JPanelu, który następnie ma być w panelu naszej głównej klasy. Gdzie może być problem?

0

Odświeżam

1 użytkowników online, w tym zalogowanych: 0, gości: 1