JMenuBar не появляется, если я не помещаю все в один класс - PullRequest
0 голосов
/ 10 сентября 2018

Я пытаюсь создать рамку с помощью панели меню, но не могу показать ее.Я попытался использовать pack(), так как это было предложено в аналогичных вопросах, но это делает мой фрейм несуществующим, я получаю только верхнюю панель окна.

Если я помещаю все в один класс, это работает;поэтому я предполагаю, что моя проблема является чем-то базовым в структуре Java.

Вот мой класс JMenuBar:

package jpaintnet;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

public class JMenuBar extends JFrame implements MenuListener, ActionListener {

    JMenuBar mb;
    JMenu addImage, addObject, save;
    JMenuItem circle, rectangle, triangle, line;

    public JMenuBar() {

        mb = new JMenuBar();

        addObject = new JMenu("Add Object");
        mb.add(addObject);

        addImage = new JMenu("Add a new image");
        mb.add(addImage);

        save = new JMenu("save");
        mb.add(save);


        circle = new JMenuItem("Create a circle");
        circle.addActionListener(this);
        addObject.add(circle);

        rectangle = new JMenuItem("Create a rectangle");
        rectangle.addActionListener(this);
        addObject.add(rectangle);

        triangle = new JMenuItem("Create a triangle");
        triangle.addActionListener(this);
        addObject.add(triangle);

        line = new JMenuItem("Create a line");
        line.addActionListener(this);
        addObject.add(line);
    }



    @Override
    public void actionPerformed(ActionEvent e) {
       //here goes everything!
    }

    @Override
    public void menuSelected(MenuEvent e) {
    }

    @Override
    public void menuDeselected(MenuEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public void menuCanceled(MenuEvent e) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

Мой класс JFrame:

package jpaintnet;

import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import java.awt.HeadlessException;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

public class Frame extends JFrame
{

    public Frame(String title) throws HeadlessException {

        JMenuBar mb = new JMenuBar();
        JPanel panel = new JPanel();

        this.setBounds(100,100,640,480);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setBackground(Color.white);

        this.getContentPane().add(BorderLayout.SOUTH, panel);
        this.getContentPane().add(BorderLayout.NORTH, mb);

        this.setVisible(true);
    }
}

И, наконец, мойmain:

package jpaintnet;

public class Main {

    public static void main(String[] args) {

        Frame f = new Frame("JPaintNet");
        f.setVisible(true);
    }
}

Я прокомментировал один из setVisible() методов, но на всякий случай поставил его здесь снова.

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 10 сентября 2018

@ Андрей, обновил ваш код, как указано ниже для вашей справки.См. Встроенные комментарии:

Вот ваш MyMenuBar, то есть класс JMenuBar:

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

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;

/*
 * 1. Renamed your class "JMenuBar" to "MyMenuBar" - do not use Java class names. Its bad practice
 * 2. Extend from JMenuBar class to create Menu Bar. Whereas JFrame requires to create a frame
 */
public class MyMenuBar extends JMenuBar implements MenuListener, ActionListener { 
  JMenu addImage, addObject, save;
  JMenuItem circle, rectangle, triangle, line;

  public MyMenuBar() {


      addObject = new JMenu("Add Object");
      add(addObject);

      addImage = new JMenu("Add a new image");
      add(addImage);

      save = new JMenu("save");
      add(save);


      circle = new JMenuItem("Create a circle");
      circle.addActionListener(this);
      addObject.add(circle);

      rectangle = new JMenuItem("Create a rectangle");
      rectangle.addActionListener(this);
      addObject.add(rectangle);

      triangle = new JMenuItem("Create a triangle");
      triangle.addActionListener(this);
      addObject.add(triangle);

      line = new JMenuItem("Create a line");
      line.addActionListener(this);
      addObject.add(line);
  }



  @Override
  public void actionPerformed(ActionEvent e) {
     //here goes everything!
  }

  @Override
  public void menuSelected(MenuEvent e) {
  }

  @Override
  public void menuDeselected(MenuEvent e) {
      throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  }

  @Override
  public void menuCanceled(MenuEvent e) {
      throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  }
}

Вот ваш MyFrame, то есть класс фреймов:

    import java.awt.BorderLayout;
import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyFrame
  extends
  JFrame {

  public MyFrame( String title ) {
    MyMenuBar mb = new MyMenuBar();
    JPanel panel = new JPanel();

    this.setBounds( 100, 100, 640, 480 );
    this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    this.setBackground( Color.white );

    this.getContentPane().add( BorderLayout.SOUTH, panel );
    // this.getContentPane().add( BorderLayout.NORTH, mb ); //Do not use this
    // method to set menu bar
    this.setJMenuBar( mb ); // this is ideal method to set menu bar

    this.setTitle( title ); // Missing as you have supplied title but missed to set it to frame
    this.setVisible( true );
  }

  // added main method here from your Main class
  public static void main( String[] args ) {

    MyFrame f = new MyFrame( "JPaintNet" );
    f.setVisible( true );
  }
}

Создает окно, например:

enter image description here

Я думаю, это то, что вы хотите все вместе.

0 голосов
/ 10 сентября 2018

Есть несколько ошибок, которые вы сделали.

  1. В вашем Frame классе удалите следующий импорт

    import javax.swing.JMenuBar;
    

    потому что после импорта swing.JMenuBar jvm будет игнорировать созданный вами JMenuBar.

  2. Ваш класс JMenuBar должен расширяться с javax.swing.JMenuBar, а не с JFrame.

    public class JMenuBar extends javax.swing.JMenuBar implements MenuListener, ActionListener
    
  3. Избавьтесь от оператора mb = new JMenuBar(); в конструкторе JMenuBar. Потому что когда вы создаете new JMenuBar(), первое, что делает jvm, вызывает его конструктор. Создание еще одного new JMenuBar() в конструкторе означает, что вы продолжаете создавать столько JMenuBar с, что в конечном итоге приведет к ошибке StackOverFlow.

  4. Удалите переменную mb из вашего JMenuBar класса и замените на this.

    this.add(addObject);
    this.add(addImage);
    this.add(save);
    

Тогда ваше окно должно работать нормально.

enter image description here


ОБНОВЛЕНИЕ:

Как и MadProgrammer предложил , имейте в виду, чтобы имена ваших классов были уникальными, особенно когда речь идет о библиотеках, разработанных java. А вот дополнительный совет: избегайте использования ключевых слов Java в качестве имен таблиц или столбцов при создании баз данных. Это избавит вас от многих неприятностей, если вы в будущем будете использовать такие фреймворки, как Hibernate.

...