Panel pod panelem

0

Witam

Myślę nad koncepcją zrealizowania takiego czegoś :

Jest JFrame a w nim panel a w panelu baton. Klikam buton i pojawia się drugi panel pod pierwszym (stykają się krawędziami). Przesuwam okno z pierwszym panelem a drugie bez odrywania przylepione do dolnej krawędzi dolnego panelu podązą za tym pierwszym.

Przychodzi mi jedynie do głowy stworzenie drugiego Jframea z panelem i ukrycie go na starcie - po kliknięciu butona by się pojawiał a jego pozycja byłaby przeliczana z przesunięcia tego pierwszego Jframea.

Trochę to pokomplikowane chyba sztucznie - jest jakiś easy way?

0

Przesuwasz okno czy pierwszy panel?

0

Nie za bardzo rozumiem co chcesz zrobić, ale może do tego wystarczyłby CardLayout?

0

No czasami ciężko napisac co się mysli dlatego zrobiłem rysunek:
user image

Jak widać cardL nie da rady - przynajmniej z mojej wiedzy (zastępuje w końcu panel innym panelem dokładnie w tym samym miejscu). Jakieś sugestie?

0

Dodawaj po prostu (lub usuwaj) do listy komponentów głównego okna (ono jest klasy JFrame?) dolny panel.

0

To nie takie proste ... mam statusbar na dole. Nad nim jest mainPanel i teraz oczywisćie moge dodawać i usuwac panele w tym panelu ale on sam po usunięciu nie skróci mi panelu tak by statusbar powrócił do początkowej pozycji. PO usunięciu mam lukę...

0
  1. Statusbar jest częścią JFrame?
  2. Jaki masz LayoutManager?
0

statusBar (panel) jest częścią JFrema. Lajałt to freedesign albo null. W sumie teraz myślę moze właśnie zmiana lajałtu by pomogła-sugestie...który najlepszy do pozycji o tej samej szerokosci rozłożonych jeden pod drugim?

0

Podobno BoxLayout. Byłem niezadowolony z dostępnych layoutów, i napisałem do rozmieszczania komponentów w słupku własny layout. Mogę udostępnić.

0

Hmm...no podeślij proszę. Tylko czy on mi automatycznie zrobi resize po usunięciu panelu? To chyba nie da się tak prosto - trzeba bedzie klepnąć to ręcznie hmm?

0

Ja bym użył BorderLayout, jest łatwy w obsłudze i ma 5 pól: NORTH, SOUTH, CENTER, WEST i EAST. Zatem ten dolny ustawiasz na South. Wadą jest to, że Center zabiera całe wolne miejsce, ale możesz użyć tylko North.
http://download.oracle.com/javase/tutorial/uiswing/layout/border.html

Musiałbyś tylko ręcznie zarządzać rozmiarem okna.

Ewentualnie JWindow i ComponentListener, żeby zawsze trzymał się pod tamtym okienkiem, ale to trochę więcej roboty

0

Działający przykład (może się jeszcze komuś przyda):

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

public class Test3 extends JFrame implements ActionListener
{
    private JPanel panel;
    private JLabel status;
    private boolean visible=false;
    //------------------------
    public static void main(String[] args)
    {
        new Test3();
    }
    //------------------------
    public Test3()
    {
        super("Test");
        setLayout(new VerticalLayout(200,2));
        for(int i=0;i<3;i++)
        {
            add(new JLabel("Etykieta "+(i+1)));
            add(new JButton("Przycisk "+(i+1)));
        }
        JButton b=new JButton("On/Off");
        b.addActionListener(this);
        add(b);
        status=new JLabel("Status:");
        add(status);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
        panel=new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.CENTER));
        panel.add(new JLabel("Idę"));
        panel.add(new JLabel("na"));
        panel.add(new JLabel("piwo"));
    }
    //------------------------
    public void actionPerformed(ActionEvent ae)
    {
        if(!visible)
        {
            remove(status);
            add(panel);
            add(status);
        }
        else
        {
            remove(panel);
        }
        visible=!visible;
        validate();
        pack();
        repaint();
    }
}

Klasę VerticalLayout wysyłam mailem.

0

Dzięki za kody. Testowałem i niestety nadają się ale nie do tego co chciałem osiągnąć. Nie mogłem zrobic tak by po usunięciu frame z automatu zmieniał się rozmiar. Więc zrobiłem oszukaństwo i sam po usunięciu panelu zmieniałem rozmiar frame'a (bylo to prawdopodobnie spowodowane tym że każdy z moich komponentów ma ustawiony setPreferedSize).
Po usuwaniu panelu znowu pojawiał się problem z dodawaniem panelu - panel ten był raczej skomplikowany - zawierał iles podpaneli, tabel etc. Musiałem usuwać wszystko idac w dół drzewa i znowu dodawać od dołu do góry - efekt był mizerny i do tego trudny w utrzymaniu.

Wiec zrobiłem po prostu zmniejszanie panelu do wysokości 0 i potem znowu go rozszerzanie. Zachowuje lajołty i ustawienie komponentów etc:

 if (!widocznoscRaportu) {
            raportPanel.setPreferredSize(new Dimension(1000, rozmiarPaneluRaportowania));
            mainPanel.setSize((int) mainPanel.getSize().getWidth(), (int) mainPanel.getSize().getHeight() + rozmiarPaneluRaportowania);
            mainPanel.validate();
            mainPanel.repaint();
            mainFrame.setBounds(mainFrame.getBounds().x, mainFrame.getBounds().y, (int) mainFrame.getSize().getWidth(), (int) mainFrame.getSize().getHeight() + rozmiarPaneluRaportowania);
            mainFrame.validate();
            mainFrame.repaint();
            widocznoscRaportu = true;

        } else {
            
            raportPanel.setPreferredSize(new Dimension(1000, 0));
            mainPanel.setSize((int) mainPanel.getSize().getWidth(), (int) mainPanel.getSize().getHeight() - rozmiarPaneluRaportowania);
            mainPanel.validate();
            mainPanel.repaint();
            mainFrame.setBounds(mainFrame.getBounds().x, mainFrame.getBounds().y, (int) mainFrame.getSize().getWidth(), (int) mainFrame.getSize().getHeight() - rozmiarPaneluRaportowania);
            mainFrame.validate();
            mainFrame.repaint();
            widocznoscRaportu = false;
        }
 

Działać działa:)

Niech mi ktos wytłumaczy czym się różni preferedsize od size - bo według mojej wiedzy pierwsze znaczyło że moze a nie musi - w zależnosci od rozmiaru komponentu wyzej w drzewie...a drugi to na twardo.

A teraz dodatek : robił ktoś może wysuwanie sie panelu płynnie? Wysuwa się i chowa ale nie od razu tylko jakoś liniowo albo i nawet nieliniowo (na początku szybko a potem wolniej).

Jeszcze sie za to nie zabralem ale wywoływanie repaint() i zmienianie size troche wydaje mi się kulwawe...

0

Mam wrażenie, że coś zrobiłeś źle (tzn. niezgodnie z przykładem).
Wywołanie pack() powoduje automatyczną zmianę rozmiaru całego okna.
Usunięcie panelu z okna usuwa wszystkie komponenty okna, nie jest potrzebna żadna zabawa z komponentami.

0

nie wiem czy dobrze zrozumiałem zadanie...

 
public class Main extends JFrame {

    JPanel basic = new JPanel();
    JPanel up = new JPanel();
    JPanel down = new JPanel();    
    JButton open = new JButton("openPane");
    JButton close = new JButton("closePane");
    JLabel lab = new JLabel("statusss");

    class ButtonOpen implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            
            basic.add(down);
            down.setBackground(Color.GREEN);
            basic.revalidate();
            basic.repaint();
        }
    }
    class ButtonClose implements ActionListener {

        public void actionPerformed(ActionEvent e) {

            basic.remove(down);
        //    down.setBackground(Color.GREEN);
            basic.revalidate();
            basic.repaint();
        }
    }
    public Main() {

        setLayout(new BorderLayout());
        add(basic,BorderLayout.CENTER);
        basic.add(up);
        basic.setLayout(new GridLayout(0,1));
        
        basic.setBackground(Color.BLUE);
        up.setBackground(Color.red);       
        up.add(open);
        up.add(close);
        open.addActionListener(new ButtonOpen());
        close.addActionListener(new ButtonClose());
        add(lab,BorderLayout.SOUTH);
        Dimension dim = new Dimension(800, 30);
        lab.setPreferredSize(dim);
        lab.setSize(dim);

    }

    public static void main(String[] args) throws IOException {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                Main fr = new Main();
                fr.setVisible(true);
                fr.setSize(800, 800);
                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}


ja standardowo używam GroupLauouta (który jest także używany przez netbeansa)

0

@remigio

Tak, dokładnie o to chodzi.

@bo

Masz rację pod warunkiem że to lajołtowi zostawia się dobranie rozmiarów do okna (Czy odwrotnie patrząc to okno po wywołaniu pack() się dosuwa).
Problem jest że ja wszystkie komponenty nie wiem dlaczego netbeans ustawia mi przez setpreferedSize. Wtedy wywołanie pack() nie daje żadnych rezultatów.

Dzięki Panowie - popracuje jeszcze. M.in. jak w netbeans zmusić by nie wstawiał domyślnych wartosci preferowanego rozmiaru. null w customize code nie pomaga.

Na razie moze i niezbyt eleganckie działanie ale działa.

EDIT: Doczytałem i setPreferedSize różni sie tym od setSize, że ten pierwszy stosujemy własnie wtedy gdy rodzic posiada lajałt. Natomiast drugi stosuje się własnie dla Jfreamów desktopów czy internalFramów oraz dla komponentów wewnątrz scrolled panes.

W netbeans każdy komponent ma domyślnie freeDesign czyli taki groupLayout - stąd poprawnie mam wszystko na setPreferedSize. Nie umiem natomiast rozwikłać JFrame...tam jest Designer Size-i tego w kodzie nigdzie znaleźć nie umiem. A wiem że ma wpływ na rozmiar bo jak zmieniam to sie zmienia. szukałem w properitisach, xmlach i kodzie i kurde nie ma.

0

Widok kodu wygenerowanego przez NetBeans i opisy walk programistów z graficznym projektantem utwierdzają mnie w dawno podjętym postanowieniu, by cały kod pisać, a nie wyklikiwać.
(Mogę na kod mogę patrzeć bez obrzydzenia.)

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