JMenu duplicate

467 views Asked by At

I have a JFrame with a JMenu. When I add a JPanel containing an image on some occasions the menu is duplicated when the program first starts. The duplicated menu disappears on resize. Any suggestions gratefully received. Thanks. Code follows:

public class MwE implements ActionListener {

    private JFrame frame;

    private String path;

    public static void main(String[] args) {
        new MwE();
    }

    public MwE(){
        frame=new JFrame();
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setSize(720,590);
        frame.setTitle("MWE");
        frame.setJMenuBar(getMenu());
        frame.setSize(new Dimension(720,590));
        frame.setVisible(true);

        File f=new File("");
        path=f.getAbsolutePath();
        String fn=path.concat("\\1077neuron.jpg");
        ImgPanel ip=new ImgPanel(fn);
        frame.setContentPane(ip);
        frame.addWindowListener(new MyWindowListener());
        frame.validate();
        frame.paintComponents(frame.getGraphics());
        return;
    }

class ImgPanel extends JPanel{
    protected  BufferedImage img;

    public ImgPanel(String F){
        try{
            img=ImageIO.read(new File(F));
        } 
        catch (IOException e){
            System.out.println(e.getMessage());
        }
    }

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.drawImage(img,0,0, null);
        }   
    }

private JMenuBar getMenu(){
    JMenuBar menuBar=new JMenuBar();
    JMenu menu=new JMenu("File");
    JMenuItem mi=new JMenuItem("OpenNetwork");
    mi.addActionListener(this);
    menu.add(mi);
    mi=new JMenuItem("SaveNetwork");
    menuBar.add(menu);
    menu=new JMenu("Help");
    mi=new JMenuItem("About");
    mi.addActionListener(this);
    menu.add(mi);
    menuBar.add(menu);
    return menuBar;
}

@Override
public void actionPerformed(ActionEvent arg0) {
    if(arg0.getActionCommand()=="About"){
        JOptionPane.showMessageDialog(frame, "MWE");
    }
}

class MyWindowListener extends WindowAdapter {
       public void windowClosing(WindowEvent e) { 
            frame.setVisible(false);
            frame.dispose();
           }
    }
}

Here is what the problem looks like: https://drive.google.com/file/d/0BxEMTvXHiBACNVZ0blZyMHBma3c/view?usp=sharing

The problem is not image specific but here is the image I used just in case it might be helpful: https://drive.google.com/file/d/0BxEMTvXHiBACUnlWOEQ5THlrVEE/view?usp=sharing

2

There are 2 answers

0
MadProgrammer On BEST ANSWER

Get rid of frame.paintComponents(frame.getGraphics());

You don't control the painting process, that is controlled by repaint manager and the underlying API. If you want the UI to be repainted, you need to make a request to the system via the repaint method

Take a look at

Also, don't call frame.setVisible(true); until you have setup the initial UI, doing otherwise can cause some elements not be updated properly. If you need to update the UI after it's been made visible, you need to ensure that you call revalidate and repaint to force the UI to update correctly...

And, unless you're intending to trap the closing event (to prompt the user for some reason), you can set the frames defaultCloseOperation to JFrame.EXIT_ON_CLOSE and save yourself some code

And if(arg0.getActionCommand()=="About"){ is not how Strings should be compared, you're comparing memory references, which are unlikely to be the same. Instead you should be using something more like if("About".equals(arg0.getActionCommand())){

1
martinez314 On

You need to start your Swing GUI in the event thread. Strange things may intermittently happen otherwise. Try this:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new MwE();
        }
    });
}

More about initial threads...