2015-01-19 5 views
0

Работа с приложением Java, которое открывает окно и позволяет пользователю рисовать на окне, например, на холсте.JMenuBar открывается в отдельном окне из приложения

Я только что добавил JMenuBar, что в конечном итоге позволит пользователю использовать различные инструменты рисования. Проблема в том, что JMenuBar открывается в отдельном окне из окна «холст», и я хочу, чтобы JMenuBar был частью того же окна.

Как мне обойти это и заставить это случиться?

Это метод, который создает строку меню:

// Create JFrame with MenuBar Components 
public static void initializeMenu() { 
    frame = new JFrame(); 

    // JMenu Bar 
    menuBar = new JMenuBar(); 
    menuBar.setBackground(Color.GRAY); 

    // JMenu 
    fileMenu = new JMenu("File"); 
    editMenu = new JMenu("Edit"); 
    menuBar.add(fileMenu); 
    menuBar.add(editMenu); 

    // JMenu Items 
    jItem = new JMenuItem("Save"); 
    fileMenu.add(jItem); 

    // Make JMenuBar Visible in Application 
    frame.setJMenuBar(menuBar); 
    frame.pack(); 
    frame.setVisible(true); 

} 

И главный метод:

// Main method 
    public static void main(String[] args) { 
     Paint paint = new Paint(); 
     paint.setSize(800, 500); 
     paint.setVisible(true); 
     paint.setLayout(new FlowLayout()); 
     initializeMenu(); 

    } 

ответ

1

Try возвращающий экземпляр JMenuBar из initializeMenu и применить его к Paint класса

public static JMenuBar initializeMenu() { 
    // JMenu Bar 
    menuBar = new JMenuBar(); 
    menuBar.setBackground(Color.GRAY); 

    // JMenu 
    fileMenu = new JMenu("File"); 
    editMenu = new JMenu("Edit"); 
    menuBar.add(fileMenu); 
    menuBar.add(editMenu); 

    // JMenu Items 
    jItem = new JMenuItem("Save"); 
    fileMenu.add(jItem); 

    return menuBar;  
} 

Затем примените его к Paint класс ...

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      Paint paint = new Paint(); 
      paint.setJMenuBar(initializeMenu());   
      paint.setLayout(new FlowLayout()); 
      paint.setSize(800, 500); 
      paint.setVisible(true); 
     } 
    }); 
} 

Лично я бы благоприятствовать pack над setSize, это обычно приводит к видимой области, которая будет соответствовать вашим потребностям (при условии, что вы используете API управления макета правильно)

Обновлено ...

разбил краска Цепь

public class Paint extends JFrame implements ... { 

    //... 

    // Method for different drawing stencils 
    public void paint(Graphics g) { 
     if (p != null) { 
      g.setColor(c); 
      switch (shapeType) { 
       case 0: 
        g.drawOval(p.x - w/2, p.y - h/2, w, h); 
        break; 
       case 1: 
        g.drawRect(p.x - w/2, p.y - h/2, w, h); 
        break; 

      } 

     } 

     // Resets application window surface to white (clears the canvas) 
     if (Refresh == true) { 
      g.setColor(Color.white); 
      g.fillRect(0, 0, 1500, 1500); 

     } 
     g.drawImage(key, 0, 0, this); 

     if (widthincrease == true) { 
      w += 1; 
     } 
     if (heightincrease == true) { 
      h += 1; 
     } 
     if (widthdecrease == true) { 
      w -= 1; 

      if (w < 1) { 
       w = 50; 
      } 
     } 

     if (heightdecrease == true) { 
      h -= 1; 

      if (h < 1) { 
       h = 50; 
      } 
     } 

     try { 
      Thread.sleep(10); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     repaint(); 
    } 

    public void update(Graphics g) { 
     paint(g); 
    } 
} 

В основном, переопределяя paint, но никогда не вызывая super.paint, вы не позволили кадру когда-либо рисовать его содержимое.

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

RootPane

Они могут (и будут) закрашивать все, что вы пытаетесь нарисовать к раме.

Рамка имеет границы, которые являются краской в ​​пределах области рамок, путем переопределения paint, вы можете рисовать под этими границами, см. How to get the EXACT middle of a screen, even when re-sized для примера того, о чем я говорю.

Вместо этого создайте собственный класс, который наследуется от JPanel и переопределить это paintComponent метод, переместить остальную часть «картины», связанные с закодировать этот класс (и не забудьте позвонить super.paintComponent, прежде чем делать какие-либо пользовательские картины).

См Performing Custom Painting для более подробной информации

KeyListener Избегайте, если серьезно, это просто краска, вместо этого, используйте ключевые привязки API см How to Use Key Bindings для более подробной информации

+0

OK.В этом есть смысл. Тем не менее мой класс Paint расширяет Frame. Итак, я получаю ошибку 'Метод setMenuBar (JMenuBar) не определен для типа Paint', поэтому я расширил JFrame, и ошибка была исправлена, хотя я не вижу JMenuBar в окне приложения все еще. Должен ли я опубликовать остальную часть моего кода? – freddiev4

+0

Ну, тогда у вас есть проблема. Вы не можете смешивать «Swing» и AWT таким образом. На самом деле, основываясь на ваших комментариях в вашем вопросе, я бы настоятельно советовал не использовать 'java.awt.Canvas' и экземпляр использовать' JPanel', таким образом, вы могли бы расширить 'Paint' из' JFrame' и решить свои проблемы. .. – MadProgrammer

+0

Рассмотрите возможность предоставления [runnable example] (https://stackoverflow.com/help/mcve), который демонстрирует вашу проблему. Это приведет к меньшему путанице и лучшим ответам – MadProgrammer

Смежные вопросы