Почему не появляется мой JMenuBar? - PullRequest
3 голосов
/ 20 февраля 2009

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

import java.awt.*;
import javax.swing.*;
import javax.swing.JPanel;
import java.awt.event.*;
import java.awt.image.*;     
import java.io.*;
import java.util.Arrays;
import javax.imageio.ImageIO;

public class selectionFrame extends JFrame
 {
  Font name;
  Font title;

  public void setup() //can't use constructer because this isn't given a size until after it is constructed.
  { 
   //getContentPane().add(menuBar);
   setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   getContentPane().setLayout(new FlowLayout());
   //getContentPane().add(j);

   setJMenuBar(createMenuBar());
   //getContentPane().add(createMenuBar());  
  }

  public JMenuBar createMenuBar()
  {
   JMenuBar menuBar;
   JMenu m_file;
   JMenuItem mi_save;
   JMenuItem mi_load;

   JMenu m_edit;
   JMenuItem mi_tileHeight;
   JMenuItem mi_tileWidth;

   menuBar = new JMenuBar();
   m_file = new JMenu("File");
   m_edit = new JMenu("Edit");

   mi_save = new JMenuItem("Save file", KeyEvent.VK_S);
   mi_load = new JMenuItem("Load file", KeyEvent.VK_L);
   mi_tileHeight = new JMenuItem("Set tile height", KeyEvent.VK_H);
   mi_tileWidth = new JMenuItem("Set tile width", KeyEvent.VK_W);

   menuBar.add(m_file);
   m_file.add(mi_save);
   m_file.add(mi_load);

   menuBar.add(m_edit);
   m_edit.add(mi_tileHeight);
   m_edit.add(mi_tileWidth);

   return menuBar;
  }

  public static void main(String[] args) //run
  { 
   selectionFrame sel = new selectionFrame();
   sel.setLocationRelativeTo(null);
   sel.setSize((int) 400 + (sel.getInsets().left + sel.getInsets().right),(int) 400  + (sel.getInsets().top + sel.getInsets().bottom));

   sel.setVisible(true);
   sel.setTitle("Tiles/Meta");
   sel.setResizable(false);
   sel.setFocusable(true);
   sel.getContentPane().setSize(sel.getSize());
   sel.setLocation((int) sel.getX() - (sel.getWidth()/2),(int) sel.getY() -  (sel.getHeight()/2));
   sel.setup();
   sel.repaint();

   } 
 }

Ответы [ 7 ]

5 голосов
/ 20 февраля 2009

У вас там очень много лишнего кода.

public class SelectionFrame extends JFrame
{
    Font name;
    Font title;

    public SelectionFrame()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setJMenuBar(createMenuBar());
    }

    public JMenuBar createMenuBar()
    {
        JMenuBar menuBar;
        JMenu m_file;
        JMenuItem mi_save;
        JMenuItem mi_load;

        JMenu m_edit;
        JMenuItem mi_tileHeight;
        JMenuItem mi_tileWidth;

        menuBar = new JMenuBar();
        m_file = new JMenu("File");
        m_edit = new JMenu("Edit");

        mi_save = new JMenuItem("Save file", KeyEvent.VK_S);
        mi_load = new JMenuItem("Load file", KeyEvent.VK_L);
        mi_tileHeight = new JMenuItem("Set tile height",
        KeyEvent.VK_H);
        mi_tileWidth = new JMenuItem("Set tile width",
        KeyEvent.VK_W);

        menuBar.add(m_file);
        m_file.add(mi_save);
        m_file.add(mi_load);

        menuBar.add(m_edit);
        m_edit.add(mi_tileHeight);
        m_edit.add(mi_tileWidth);

        return menuBar;
    }

    public void main( String args[] )
    {

        SelectionFrame sel = new SelectionFrame();
        sel.setLocationRelativeTo(null);
        sel.setSize(400 + (sel.getInsets().left + > sel.getInsets().right), 400
        + (sel.getInsets().top + sel.getInsets().bottom));

        sel.setTitle("Tiles/Meta");
        sel.setResizable(false);
        sel.setFocusable(true);

        sel.getContentPane().add( new JLabel( "Content", SwingConstants.CENTER),
         BorderLayout.CENTER );
        sel.setLocation(sel.getX() - (sel.getWidth() / 2), sel.getY() - >             (sel.getHeight() / 2));
        sel.setVisible(true);

    }
}

Это проявляется в строке меню и всё. если вы добавляете свой контент в ЦЕНТР панели контента (по умолчанию макет границы), центр автоматически заполняет всю область контента, вам не нужно ничего менять размер.

Это отображается как окно с строкой меню, и все работает нормально.

На какой платформе вы это делаете? Я на Vista, я получаю то, что ожидаю увидеть.

1 голос
/ 16 августа 2012

В моем случае я отследил отсутствующую строку меню до ошибки, в которой я установил макет RootPane , tsk tsk. RootPane (см., Например, http://download.java.net/jdk7/archive/b123/docs/api/javax/swing/JRootPane.html) контролирует компоновку строки меню, поэтому, когда я изменил ее менеджер компоновки, она потеряла панель.

Вместо этого следует использовать ContentPane для размещения и добавления компонентов, например:

frame.getContentPane().setLayout(...);
frame.getContentPane().add(...);

Для дальнейшего использования ... это не имеет ничего общего с видимым компонентом (как сказал OP, рамка видима, а строка меню нет), у меня есть рабочий код, который устанавливает JMenuBar вне конструктора, Хорошей практикой является то, что она безопасна для работы с колебаниями, но это не является причиной проблемы.

1 голос
/ 20 февраля 2009

Оказывается, вы ЕСТЬ , чтобы установить JMenuBar внутри конструктора JFrame. Я понял это, глядя на различия между моим кодом и помеченным кодом ответов.

Спасибо за ваш чудесный ответ, Джон Гарднер. Без тебя я бы скорее всего застрял на месяцы.

1 голос
/ 20 февраля 2009

Какую версию Java вы используете? Ваша строка меню хорошо отображается в 1.6.0_10 в моей системе. Попробуйте обернуть тело вашего метода main в вызов invokeLater(), чтобы он выполнялся в правильном потоке, например:

public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                selectionFrame sel = new selectionFrame();
                sel.setLocationRelativeTo(null);
                sel.setSize((int) 400 + (sel.getInsets().left + sel.getInsets().right), 
                            (int) 400 + (sel.getInsets().top + sel.getInsets().bottom));
                sel.setTitle("Tiles/Meta");
                sel.setResizable(false);
                sel.setFocusable(true);
                sel.getContentPane().setSize(sel.getSize());
                sel.setLocation((int) sel.getX() - (sel.getWidth() / 2),
                                (int) sel.getY() - (sel.getHeight() / 2));
                sel.setup();
                sel.setVisible(true); // Follow Kendrick's advice too.
            }
        });
    }
0 голосов
/ 20 февраля 2009

Кроме того, непосредственно перед вызовом sel.setVisible(true); просьба вызвать sel.pack();

Пожалуйста, обратите внимание, что вместо setSize лучше использовать setPreferredSize, который используется при упаковке рамы.

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

0 голосов
/ 20 февраля 2009

sel.setVisible (истина);

Должно быть последнее, что вы называете ......

0 голосов
/ 20 февраля 2009

Когда я компилирую и запускаю его, он отображается в строке меню с файлами и редактирует пункты меню. Вы ожидали большего?

Кроме того, заглавная буква вашего класса - SelectionFrame

EDIT: Одна вещь, на которую я забыл взглянуть, твой код и каждый ответ здесь технически неверны. Часто это срабатывает, но вам не разрешено ничего делать с компонентами Swing, если вы не находитесь в рабочем потоке AWT .

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

Sun обычно рекомендовал вам работать с компонентами вне потока AWT до тех пор, пока окно не будет реализовано (с помощью pack () или setVisible (true)), но это больше не считается безопасным .

Самый простой способ исправить это - создать основной рабочий поток для вашего основного устройства перед обновлением вашего SelectionFrame.

Существует всего 50-50 шансов, что это решит вашу проблему, но вы все равно должны учитывать это при работе с графическим интерфейсом.

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