Programowanie obiektowe i GUI

0

Cześć,

Konstruując graficzny interfejs użytkownika zacząłem się zastanawiać, czy powinienem go podzielić na elementy składowe?

GUI składa się z JFrame i kilku JPanel'ów, które w zależności od wybranych opcji będą widoczne lub nie (każdy JPanel ma taką samą wielkość). Planuję użyć metody setVisible() do poruszania się pomiędzy poszczególnymi JPanel'ami w trakcie działania programu.

Jeżeli umieszczanie elementów GUI w różnych klasach to dobra praktyka, to potrzebuję jeszcze pomocy w formie prostego przykładu - jednej klasy głównej z JFrame i drugiej z JPanel'em, który pojawi się po uruchomieniu w oknie. Próbowałem sam to napisać, ale póki co bez efektów. Mogę ewentualnie zamieścić kod do wskazania błędów.

Dzięki!

0

Tworzysz klasę główną, tworzysz klasę, która prezentuje jakieś okienko.

W klasie głównej wywołujesz nowe okienko w ten sposób:
new JakasKlasa().setVisible(true);

0

Proszę o wskazanie błędu w tym, co napisałem - kompiluje się bez problemu, ale JButton się nie pojawia w oknie.

JFrameTest.java

package jframetest;

import java.awt.FlowLayout;
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);
        
        JPanelOne panel = new JPanelOne();
        panelMain.add(panel);

    }
    
    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);
        
    }
    
}
0
panelMain

tego panelu nie dodałeś do głównego okna.

this.add(panelMain);
0

Edytowałem plik JFrameTest.java: dodałem

add(panelMain);

na końcu metody JFramTest() i JPanel z drugiej klasy dalej nie jest widoczny w oknie. Dodałem też jeden JButton do panelMain, który jest widoczny w oknie po uruchomieniu programu.

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);
                

    }
}

0

Może drugi panel jest za duży i się nie mieści w oknie.

0

A co dodałeś do contentPane?
Samo contentPane uzyskujesz przez JFrame.getContentPane().

ps. setVisible(true) włącza się dopiero po dodaniu wszystkich komponentów ponieważ instrukcja ta wywołana pierwszy raz dla okna top-level konstruuje okno, które jest typu heavy-weight, czyli częściowo poza kontrolą JVM. Późniejsze add wymusza wykonanie validateTree od poziomu kontenera do którego się coś dodało, aby komponenty zostały zaktualizowane w już otwartym oknie. Może to też czasem wymagać repaint().
Dodawanie setVisible(true) do komponentów niższego poziomu przed skonstruowaniem okna jest nadmiarowe ponieważ taki stan mają z automatu. Można wyłączać "niższe" komponenty w oknie przez setVisible(false), a potem z powrotem włączać, ale ma to sens tylko na oknie, które jest już skonstruowane i widoczne. Ewentualnie jest sens ustawiać setVisible(false) dla komponentów w oknie jeżeli po skonstruowaniu okna mają się one nie pojawić od razu (a dopiero na żądanie później).

0

Coś takiego? http://imageshack.us/photo/my-images/545/przykadj.jpg/

W każdym razie tu masz kod


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
{

	public JFrameTest()
	{
		initComponents();

	}

	private void initComponents()
	{
		setLayout(null);
		setPreferredSize(new Dimension(400, 400));
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		panel = new JPanelOne();
		panel.setBackground(Color.BLACK); 
		panel.setBounds(200, 200, 200, 200);  // gdy zadeklarujemy setLayout(null) należy powiedzieć, gdzie dodawany komponent ma leżeć
		add(panel);


		panelMain = new JPanel();
		panelMain.setBackground(Color.WHITE);
		panelMain.setBounds(0, 0, 200, 200);
		panelMain.setPreferredSize(new Dimension(200, 200));
	
		add(panelMain);


		testButton = new JButton("Test12");

		panelMain.add(testButton);

		pack();

	}

	public static void main(String[] arguments)
	{

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

	}

	private javax.swing.JButton testButton;
	private javax.swing.JPanel panelMain;
	private JPanelOne panel;
}

I kod Twojej klasy z panelem:

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

public class JPanelOne extends JPanel
{

	public JPanelOne()
	{

		JPanel panel = new JPanel();
		panel.setPreferredSize(new Dimension(200, 200));
		panel.setBackground(Color.BLACK);

		JButton button = new JButton("test");

		panel.add(button);

		add(panel);
	}
}

Pozdrawiam. A btw jak dodajesz jakieś obiekty na panele, albo w ogóle do jframe'a to myślę, że dobrym wyborem będzie GroupLayout. Troszkę jest z nim zabawy, ale ładnie można wszystko poustawiać :)

PS aha, a jak chcesz, żeby panel czarny znajdował się "W" panelu białym, to napisz w głównej klasie tak:

private void initComponents()
	{
		setLayout(null);
		setPreferredSize(new Dimension(400, 400));
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		panelMain = new JPanel();
		panelMain.setBackground(Color.WHITE);
		panelMain.setBounds(0, 0, 200, 200);
		panelMain.setPreferredSize(new Dimension(200, 200));
	
		add(panelMain);
                

                // Zwróć uwagę, że element, który dodaję do głównego panelu tworzę i dodaję po utworzeniu głównego panelu
                panel = new JPanelOne();
		panel.setBackground(Color.BLACK); 
		panel.setBounds(200, 200, 200, 200);  
		panelMain.add(panel);


		testButton = new JButton("Test12");

		panelMain.add(testButton);

		pack();

	}

Pozdro

0

Dzięki za odpowiedzi i wskazówki!

Użytkownik Hilek rozwiązał mój problem z JPanelem tworzonym z innej klasy niż ta tworząca JFrame.

Co do wyboru samego Layout Managera, to wybrałem i korzystam z MigLayout. Aktualnie (część - widok z podstawowymi ustawieniami) mojego GUI wygląda tak:

user image

A cały problem, który sobie znalazłem sprowadza się do tego, czy zyskam cokolwiek dzieląc GUI na części (klasy) składowe, tak jak na tym obrazku:

user image

Czy dobrą praktyką jest pozostawienie całego gui w jednej klasie, czy raczej dzieli się je na osobne klasy dla każdego z elementów GUI?

Poświęciłem też trochę więcej uwagi menagerowi CardLayout. Przeczytałem jeszcze raz, to co jest o nim napisane na stronie Oracle i zauważyłem (na co wcześniej nie zwróciłem uwagi), że to nie tylko Tabbed Pane, ale można go też wykorzystać bez tworzenia menu z zakładkami. W związku z czym w tym momencie skłaniam się ku użyciu CardLayout do zorganizowania poszczególnych JPanel'i układanych przy użyciu MigLayout'a.

nowy użytkownik nie może wstawiać obrazków do wiadomości, czy to ja zrobiłem coś źle?

0

GUI powinienes rozbijac na rozne klasy. Kod jest bardziej czytelny i jakiekolwiek zmiany w przyszlosci beda latwiejsze.

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