2015-02-05 60 views
0

我的主要Java程序(MyFrame)应该使用由其他类(MyPanel)启动的其他JPanel来更新其JFrame中的现有ContentPanel,具体取决于所点击的JMenuItem并且新的JPanel的参数将被传递。当我单击JMenuItem时,JPanel不会更新,直到调整窗口大小后,它才会在第一个之后,而不是在前景中。请你能帮我解决这个问题吗?从外部类更新JPanel将只添加另一个,但不会替换它

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; 

    } 

} 
+1

add revalidate();重绘();在新的面板添加 – StanislavL 2015-02-05 13:49:39

+0

抱歉,但没有效果,新添加的面板仍然是第一个..请编译我的例子,运行它,并调整帧的大小。你会看到它会被添加到背景中。 – BrainWorx 2015-02-05 14:01:46

+1

问题是,你仍然*有一个前面的面板。然后你在中间位置有多个面板,而'BorderLayout'只能对应一个面板。您需要在添加新的之前将其删除(然后重新验证+重新绘制)。 'contentContainer.remove(0)'会对上面的示例有效。也就是说,当你考虑更换组件时,[CardLayout](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html)往往是更好的选择。 – kiheru 2015-02-05 14:18:16

回答

2

当我添加removeAll调用,它似乎工作。

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(); 
    } 
} 
  • 我还包裹着你的主要方法,在EventQueue.invokeLater通话,以确保所有Swing操作发生在美国东部时间
  • 我删除了所有相关的对话框中的代码,因为这是不需要证明的问题。内联一些其他方法来降低代码片段进一步

的长度和金色尖如果你需要调试这样的情况:按CTRL转变F1当你JFrame集中。这将打印出该组件的Swing层次结构。这样做与您的原始代码清楚地显示内容窗格包含多个MyPanel实例。

+0

你真棒,非常感谢。 – BrainWorx 2015-02-05 14:39:25

相关问题