从外部类更新 JPanel 只会添加另一个但不会替换它 [英] Updating JPanel from external class will just add another one but dont replace it

查看:32
本文介绍了从外部类更新 JPanel 只会添加另一个但不会替换它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的主 Java 程序 (MyFrame) 应根据单击的 JMenuItem 和传递新 JPanel 的参数,使用由其他类 (MyPanel) 启动的其他 JPanel 更新其 JFrame 中的现有 ContentPanel.当我单击 JMenuItem 时,JPanel 不会更新,它在第一个之后而不是在前台,直到我调整窗口大小.请问你能帮我解决这个问题吗?

My main Java program (MyFrame) should update an existing ContentPanel in its JFrame with an other JPanel initiated by an other class (MyPanel) depending on what JMenuItem is clicked and a parameter for the new JPanel will be passed. When I click the JMenuItem, the JPanel dont update, it is behind the first one and not in foreground until I resize the window. Please can you help me solve this?

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

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

public class MyFrame extends JFrame { 

private Container contentContainer;

    public static void main(String[] args) {

        new MyFrame();

    }

    public MyFrame() {

        setTitle("MyFrame");
        setSize(300, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        setJMenuBar(createMenu());

        MyPanel panel = makePanel(new String("Test oO"));

        contentContainer = this.getContentPane();
        setVisible(true);

    }

    public JMenuBar createMenu() {

        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu("Menu");       

        JMenuItem menuItem = new JMenuItem("Test");
        menuItem.setMnemonic(KeyEvent.VK_E);
        menuItem.setToolTipText("Test");

        menuItem.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {                

                MyPanel dynamicPanel = makePanel(new String("Test"));
                contentContainer.add(dynamicPanel);
                contentContainer.revalidate(); 
                contentContainer.repaint();

            }

        });

        menu.add(menuItem);

        JMenuItem menuItem1 = new JMenuItem("Test 1");
        menuItem1.setMnemonic(KeyEvent.VK_E);
        menuItem1.setToolTipText("Test 1");

        menuItem1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {

                MyPanel dynamicPanel1 = makePanel(new String("Test 1"));
                contentContainer.add(dynamicPanel1);
                revalidate(); 
                repaint();

            }

        });

        menu.add(menuItem1);


        JMenuItem menuItem2 = new JMenuItem("Dialog");
        menuItem2.setMnemonic(KeyEvent.VK_E);
        menuItem2.setToolTipText("Dialog");

        menuItem2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {

                makeDialog(new String("Zur Info"), new String("Du hast Edit geklickt"));

            }

        });

        menu.add(menuItem2);


        menuBar.add(menu);

        return menuBar;

    }

    public JDialog makeDialog(String title, String content) {

        JDialog meinJDialog = new JDialog();
        meinJDialog.setTitle(title);
        JTextArea contentArea = new JTextArea(content);
        contentArea.setEditable(false);
        meinJDialog.add(contentArea);
        meinJDialog.setSize(200,200);
        meinJDialog.setModal(true);
        meinJDialog.setLocationRelativeTo(null);
        meinJDialog.setVisible(true);
        return meinJDialog;   

    }  

    public MyPanel makePanel(String config) {

        MyPanel panel = new MyPanel(config);
        panel.revalidate(); 
        panel.repaint();
        return panel;

    }  

}

class MyPanel extends JPanel {

    public MyPanel(String config) {

        JButton testButton = new JButton(config);
        add(testButton);
        setVisible(true);
        revalidate(); 
        repaint();
        return;

    }

}

推荐答案

当我添加 removeAll 调用时,它似乎有效.

When I add removeAll calls, it seems to work.

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

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

public class MyFrame extends JFrame {

  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        new MyFrame();
      }
    });
  }

  private final Container contentContainer;

  public MyFrame() {

    setTitle("MyFrame");
    setSize(300, 200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    setJMenuBar(createMenu());
    contentContainer = getContentPane();
    contentContainer.add(new MyPanel("Test oO"));

    setVisible(true);
  }

  public JMenuBar createMenu() {

    JMenuBar menuBar = new JMenuBar();

    JMenu menu = new JMenu("Menu");

    JMenuItem menuItem = new JMenuItem("Test");
    menuItem.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        MyPanel dynamicPanel = new MyPanel("Test");
        contentContainer.removeAll();
        contentContainer.add(dynamicPanel);
        contentContainer.revalidate();
        contentContainer.repaint();
      }
    });

    menu.add(menuItem);

    JMenuItem menuItem1 = new JMenuItem("Test 1");
    menuItem1.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent event) {
        contentContainer.removeAll();
        contentContainer.add(new MyPanel("Test 1"));
        contentContainer.revalidate();
        contentContainer.repaint();
      }
    });
    menu.add(menuItem1);

    menuBar.add(menu);
    return menuBar;
  }

}

class MyPanel extends JPanel {

  public MyPanel(String config) {
    JButton testButton = new JButton(config);
    add(testButton);
    setVisible(true);
    revalidate();
    repaint();
  }
}

  • 我还将您的 main 方法封装在 EventQueue.invokeLater 调用中,以确保所有 Swing 操作都发生在 EDT 上
  • 我删除了与对话框相关的所有代码,因为这不需要演示问题.内联了一些其他方法以进一步减少代码片段的长度
    • I also wrapped your main method in an EventQueue.invokeLater call to make sure all Swing operations happen on the EDT
    • I removed all the code related to the dialog, as this was unneeded to demonstrate the problem. Inlined some other methods to reduce the length of the code snippet further
    • 还有黄金提示,如果你需要调试这样的情况:按下ctrlshiftF1JFrame 聚焦.这将打印出该组件的 Swing 层次结构.使用原始代码执行此操作清楚地表明内容窗格包含多个 MyPanel 实例.

      And the golden tip if you need to debug situations like that: press ctrlshiftF1 when your JFrame is focused. This will print out the Swing hierarchy of that component. Doing this with your original code clearly shows that the content pane contains multiple MyPanel instances.

      这篇关于从外部类更新 JPanel 只会添加另一个但不会替换它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆