Java изменить вид из меню не работает - PullRequest
2 голосов
/ 20 февраля 2012

Мне обычно не нужно задавать вопросы по Java, но сейчас я застрял больше, чем когда-либо, и думаю, что просто что-то упускаю снова и снова ..

У меня есть приложение JFrame, в котором есть JMenuBar. Элементы в строке меню имеют мой класс PageManager в качестве ActionListener. Отладка показывает, что все работает нормально. Весь лот инициализируется так:

    public static void main(String[] args) {
    UI ui = new UI();                       //The JFrame
    PageManager pm = new PageManager(ui);   //Menu ActionListener
    MenuBar mb = new MenuBar(pm);           //MenuBar
    ui.setJMenuBar(mb);
    ui.setDefaultCloseOperation(0);
    ui.setVisible(true);
    ui.setPage(new Home().getPanel());      //a View
}

В классе пользовательского интерфейса у меня есть следующий метод:

    public void setPage(JPanel p) {
    System.out.println("Set page");
    this.remove(page);
    System.out.println("Removed");
    this.add(p);
    System.out.println("Added " + p);
}

Вызов метода ui.setPage(new Home().getPanel()); работает нормально. Если я перенесу его в конструктор PageManager, он тоже будет работать. Если я заменю его на ui.setPage(new Preferences().getPanel());, это тоже работает. Классы Home и Preferences - это Views, которые создают JPanel и возвращают его с помощью метода getPanel.

Однако изменение страницы с помощью ActionListener, похоже, не работает. ВСЕ строки System.out.println печатаются нормально, но страница не изменяется. Я использую это в PageManager:

private void changePage(String s, int i) {
    if(s.equals("P")) {
        //Program options
        System.out.println("program options");
        if(i == 1) {
            ui.setPage(pref.getPanel());
        }
    } else if(s.equals("C")) {
        //Connection options
    } else if(s.equals("A")) {
        //Add rule
    }
}

(ActionListener забирает событие, проверяет источник и вызывает с ним changePage).

Дело в том, что все работает и, кажется, работает нормально в зависимости от вывода на консоль, но страница не изменится, что бы я ни делал (включая небольшие модификации).

Любая помощь будет очень признательна !!!

С уважением, Mark

Ответы [ 2 ]

4 голосов
/ 20 февраля 2012

Обычно для достижения такого поведения проще всего использовать CardLayout .

И, более того, после добавления новой панели в уже существующий JFrame, удалив старую, попробуйте revalidate() и repaint(), чтобы можно было реализовать новое дополнение.

Если ваш JDK равен 1.6 или ниже, то проведите повторную проверку на работу без фрейма, вместо этого используйте frameObject.getRootPane().revalidate();

revalidate() on JFrame is directly used with JDK 7+

Вот один пример кода, который поможет вам, с добавлением JMenuBar:

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

public class FrameTest extends JFrame
{
    public FrameTest()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationByPlatform(true);        

        final JPanel panel1 = new JPanel();
        panel1.setBackground(Color.BLUE);
        final JPanel panel2 = new JPanel();
        panel2.setBackground(Color.DARK_GRAY);

        JMenuBar menuBar = new JMenuBar();

        JMenu menu1 = new JMenu("MENU 1");
        JMenu menu2 = new JMenu("MENU 2");
        JMenu menu3 = new JMenu("MENU 3");


        JMenuItem menuItem1 = new JMenuItem("CHANGE PANELS");     
        JMenuItem menuItem2 = new JMenuItem("MENU ITEM 2");
        JMenuItem menuItem3 = new JMenuItem("MENU ITEM 3");
        menuItem1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (panel1.isShowing())
                {
                    remove(panel1);
                    add(panel2, BorderLayout.CENTER);
                }
                else if (panel2.isShowing())
                {
                    remove(panel2);
                    add(panel1, BorderLayout.CENTER);
                }
                // for getRootPane().revalidate();
                revalidate(); // For JDK 7+
                repaint();
            }
        });

        menu1.add(menuItem1);
        menu2.add(menuItem2);
        menu3.add(menuItem3);

        menuBar.add(menu1);
        menuBar.add(menu2);
        menuBar.add(menu3);

        JButton button = new JButton("CHANGE");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                if (panel1.isShowing())
                {
                    remove(panel1);
                    add(panel2, BorderLayout.CENTER);
                }
                else if (panel2.isShowing())
                {
                    remove(panel2);
                    add(panel1, BorderLayout.CENTER);
                }
                // for getRootPane().revalidate();
                revalidate(); // For JDK 7+
                repaint();
            }
        });

        add(panel1, BorderLayout.CENTER);
        add(button, BorderLayout.PAGE_END);
        setJMenuBar(menuBar);
        setSize(200, 200);
        setVisible(true);
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new FrameTest();
            }
        });
    }
}
2 голосов
/ 20 февраля 2012

При изменении иерархии компонентов видимого компонента вы должны проверить иерархию, чтобы ваши изменения были видимыми. См. JavaDoc метода remove () :

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...