Переключение между JPanels в JFrame

#java #swing #jframe #jpanel

#java #swing #jframe #jpanel

Вопрос:

На данный момент только для целей тестирования я хотел бы менять JPanel в JFrame каждый раз, когда на него нажимают. Я перебираю 3 панели / страницы, каждая из которых имеет свой уникальный цвет фона.

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

Код:

 @Override
    public void mouseClicked(MouseEvent e) {
        mainFrame.changePage();
    }

public void changePage() {
    if(currentPage != null) {
        this.remove(currentPage);
    }
    currentPage = pages[pageNumber];
    this.add(currentPage);
    currentPage.setPage();
    super.repaint();
    pageNumber  ;
    if(pageNumber > 2) {
        pageNumber = 0;
    }
}
 

Комментарии:

1. Используйте a CardLayout для замены панелей. Прочитайте раздел из руководства по Swing о том, как использовать CardLayout для получения дополнительной информации и примеров, которые помогут вам начать.

Ответ №1:

Кроме комментария от @camickr для использования CardLayout , вам необходимо revalidate . Изменение:

 super.repaint();
 

Для

 revalidate();
 

Комментарии:

1. И причина, по которой вам нужен revalidate(), заключается в том, что диспетчер компоновки устанавливает только размер / расположение исходной панели, которую вы отображаете. Когда вы меняете местами панели, вам нужен метод revalidate() для вызова диспетчера компоновки, чтобы теперь текущей панели можно было присвоить размер / местоположение. Или вместо этого вы можете использовать API, чтобы не изобретать велосипед. CardLayout делает все это за вас, поэтому вам не нужно беспокоиться об этом.

2. Я не понимаю, почему это еще не было отмечено как принятый ответ

3. @nix_s Спасибо, теперь он работает с revalidate()! — это может решить проблему, но это не должно быть решением, которое вы используете. Научитесь использовать Swing так, как он был разработан, и не изобретайте велосипед. Вы все еще не подтвердили, что прочитали CardLayout в попытке понять, почему его следует использовать. CardLayout Even поддерживает функцию «next», поэтому вам даже не нужно отслеживать, на какой панели вы находитесь. Если вы правильно используете API, у вас будет меньше проблем в будущем.

4. Понятно. Теперь я попытаюсь реализовать CardLayout и вернусь, если у меня возникнут какие-либо проблемы. Большое вам спасибо.

Ответ №2:

РЕДАКТИРОВАТЬ: поскольку @camickr упомянул, что мой приведенный ниже код не соответствует рекомендациям, пожалуйста, обратитесь к следующей ссылке о том, как использовать CardLayout.

Как использовать CardLayout — учебные пособия по Java

Связанный источник


просто для целей тестирования

Делая акцент на вышесказанном, вот несколько примеров кода. Это НЕ производственный класс, просто POC без необходимости использования CardLayout, упомянутого @camickr.

 import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class FirstSwingExample {  
    
    public static void main(String[] args) {  
        Swinger s = new Swinger();
    }
  
}

class Swinger implements ActionListener {
    
    int currFrame = 1;
    JFrame f;
    JLabel lblPanelOne, lblPanelTwo, lblPanelThree;
    JPanel panelOne, panelTwo, panelThree;
    JButton b;
    
    public Swinger() {
        setup();
    }
    
    private void setup() {
        
        f=new JFrame();
        
        panelOne = new JPanel();
        lblPanelOne = new JLabel("Panel One");
        panelOne.setBounds(0,0,100, 40);
        panelOne.setBackground(Color.BLACK);
        panelOne.add(lblPanelOne);
        
        
        panelTwo = new JPanel();
        lblPanelTwo = new JLabel("Panel Two");
        panelTwo.setBounds(0,0,100, 40);
        panelTwo.setBackground(Color.BLUE);
        panelTwo.add(lblPanelTwo);
        
        panelThree = new JPanel();
        lblPanelThree = new JLabel("Panel Three");
        panelThree.setBounds(0,0,100, 40);
        panelThree.setBackground(Color.GREEN);
        panelThree.add(lblPanelThree);
        
        b=new JButton("Panel Two");
        b.setBounds(130,100,100, 40);
        b.setActionCommand("click");
        b.addActionListener(this);
        
        panelOne.setVisible(true);
        f.add(panelOne);
        f.add(b);

        f.setSize(400,500);  
        f.setLayout(null);  
        f.setVisible(true);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e.getActionCommand());
        if(e.getActionCommand().equals("click")) {
            switch(currFrame) {
                case 1:
                    panelOne.setVisible(false);
                    f.remove(panelOne);
                    panelTwo.setVisible(true);
                    f.add(panelTwo);
                    b.setText("Panel Three");
                    currFrame  ;
                    break;
                
                case 2:
                    panelTwo.setVisible(false);
                    f.remove(panelTwo);
                    f.add(panelThree);
                    panelThree.setVisible(true);
                    b.setText("Panel One");
                    currFrame  ;
                    break;
            
                default:
                    panelThree.setVisible(false);
                    f.remove(panelThree);
                    f.add(panelOne);
                    panelOne.setVisible(true);
                    b.setText("Panel Two");
                    currFrame = 1;
                    break;
            }
        }
    }
}
 

Комментарии:

1. (1-) Swing был разработан для использования с менеджерами компоновки. Не используйте нулевой макет. Не используйте setBounds() . Не изобретайте велосипед. Не используйте оператор switch для замены панелей. Что делать, если у вас 10 панелей?? Код становится беспорядочным и не поддерживается. Научитесь использовать существующие API, чтобы код был простым и удобным в обслуживании.

2. @camickr Я уже разъяснил в самом начале, что это было просто доказательство концепции. Пожалуйста, прочитайте мой ответ полностью. Я был бы признателен, если бы вы могли отозвать понижающий голос.

3. Это плохой ответ по причинам, указанным в моем комментарии. Я никому не рекомендую следовать этому подходу к решению проблемы.