JPanel в чертеже JFrame поверх меню JFrame - PullRequest
3 голосов
/ 04 февраля 2012

Итак, у меня есть объект JPanel в качестве компонента JFrame, и я периодически перерисовываю содержимое JPanel с помощью объекта Timer.Все работает нормально, за исключением того, что JPanel перерисовывается поверх меню JFrame, поэтому пункты меню не читаются.Есть ли способ обойти эту проблему, не останавливая таймер каждый раз, когда пользователь заходит в меню?

Класс управляющего кадра

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class ControlFrame extends JFrame implements ActionListener{
    /*======Public Constants======*/
    public static int DEFAULT_HEIGHT = 400;
    public static int DEFAULT_WIDTH = 400;

    /*======Private Instance Variables======*/
    private AnimationPanel animPane;
    private JMenu menu;
    private JMenuItem menuExit;
    private JMenuBar menuBar;

    /*======Constructors======*/
    public ControlFrame(){
        initialize();
    }

    /*======Public Instance Methods======*/
    public void actionPerformed(ActionEvent ae) {
        if(ae.getActionCommand().equals("exit")){
                System.exit(0);
        }
    }

    /*======Private Instance Methods======*/
    private void initialize(){
        this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setLayout(new GridLayout(0,2));

        this.animPane = new AnimationPanel(this.getWidth(), this.getHeight());

        this.add(animPane);

        createCFMenu();

        this.setVisible(true);
    }

    private void createCFMenu(){
        this.menuBar = new JMenuBar();
        this.menu = new JMenu("File");
        this.menu.setMnemonic(KeyEvent.VK_F);
        this.menuBar.add(this.menu);

        this.menuExit = new JMenuItem("Exit", KeyEvent.VK_X);
        this.menuExit.addActionListener(this);
        this.menuExit.setActionCommand("exit");
        this.menu.add(menuExit);

        this.setJMenuBar(this.menuBar);
    }

    /*======Main Method======*/
    public static void main(String[] args){
        ControlFrame cf = new ControlFrame();


    }

}

Класс AnimationPanel

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;

public class AnimationPanel extends JPanel implements ActionListener{



    /*======Private Instance Variables======*/
    private int timeInterval;
    private Timer animTimer;

    /*======Constructor======*/
    public AnimationPanel(int width, int height){
        timeInterval = 50;

        this.setSize(width, height);

        this.animTimer = new Timer(timeInterval, this);

        animTimer.start();
    }


    public void actionPerformed(ActionEvent arg0) {

        paint();
    }

    /*======Private Instance Variables======*/
    private void paint(){
        BufferedImage bImage = new BufferedImage(this.getWidth(), 
            this.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics bg = bImage.getGraphics();

        bg.setColor(Color.WHITE);
        bg.fillRect(0, 0, bImage.getWidth(), bImage.getHeight());

        this.getGraphics().drawImage(bImage, 0, 0, this);
    }
} 

Проблема в том, что панель анимации рисует поверх меню ControlFrames

Ответы [ 2 ]

4 голосов
/ 04 февраля 2012

Одна проблема с вашим кодом - вы рисуете все неправильно.Вы почти никогда не используете getGraphics компонента для получения его объекта Graphics, так как этот объект не будет сохраняться, если есть перерисовки.Вместо этого рисование должно выполняться пассивно в методе paintComponent вашей JPanel.

Редактировать: как Эндрю показывает в своем более быстром посте!1+ ему!

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

4 голосов
/ 04 февраля 2012

Не вызывайте getGraphics() в коде Java. Графический интерфейс Java должен перерисовываться, когда ему приказано сделать это, и должен использовать либо paint(Graphics), либо paintComponent(Graphics). Вот почему меню исчезало.

Ошибка устранена в этой версии AnimationPanel.

class AnimationPanel extends JPanel implements ActionListener{
    /*======Private Instance Variables======*/
    private int timeInterval;
    private Timer animTimer;

    /*======Constructor======*/
    public AnimationPanel(int width, int height){
        timeInterval = 50;
        this.setSize(width, height);
        this.animTimer = new Timer(timeInterval, this);
        animTimer.start();
    }

    public void actionPerformed(ActionEvent arg0) {
        repaint();
    }

    /*======Private Instance Variables======*/
    public void paintComponent(Graphics g){
        // important to get the component to paint itself & borders etc.
        super.paintComponent(g); 
        BufferedImage bImage = new BufferedImage(this.getWidth(),
            this.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics bg = bImage.getGraphics();

        bg.setColor(Color.WHITE);
        bg.fillRect(0, 0, bImage.getWidth(), bImage.getHeight());
        bg.dispose();  // Assist the garbage collector!

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