Keylistener и JMenuBar проблема

Строка меню не будет рисоваться, а список ключей не будет работать. Должен ли я добавить строку меню на панель или панель содержимого? Что я делаю неправильно? Что делать? Помогите? Спасибо!

Пожалуйста, сначала скопируйте и запустите код.

КЛАСС DRAWINGDEMO

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

public class DrawingDemo extends JFrame implements ActionListener, KeyListener{
DrawingPanel demo = new DrawingPanel();
public DrawingDemo()
{

getContentPane().add(demo);
setVisible(true);
setSize(1024,720);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);

JPanel p = new JPanel();
JMenuBar mb = new JMenuBar();
JMenu file = new JMenu("File");
JMenu edit = new JMenu("Edit");
JMenu settings = new JMenu("Settings");
JMenu help = new JMenu("Help");
JMenuItem exit = new JMenuItem(">Exit");
JMenuItem imp = new JMenuItem(">Import");
JMenuItem exp = new JMenuItem(">Export");
JMenuItem sav = new JMenuItem(">Save");
JMenuItem ope = new JMenuItem(">Open");
file.add(ope);  
file.add(sav);
file.add(imp);
file.add(exp);
file.add(exit);
mb.add(file);
mb.add(edit);
mb.add(settings);
mb.add(help);
setJMenuBar(mb);

while(true){
 demo.repaint();
}
}
public void actionPerformed(java.awt.event.ActionEvent e)
{
}
public void KeyEvent(java.awt.event.ActionEvent e)
{
}
public void keyReleased(java.awt.event.KeyEvent e)
{
}
public void keyPressed(java.awt.event.KeyEvent e)
 {
 switch (e.getKeyCode()){
    case KeyEvent.VK_A : 
    {
    demo.pos_camx -= 0.5;
    }
    break;
    case KeyEvent.VK_D :
    {
    demo.pos_camx += 0.5;
    }
    break;
    case KeyEvent.VK_W :
    {
    demo.pos_camy += 0.5;
    }
    break;
    case KeyEvent.VK_S :
    {
    demo.pos_camy -= 0.5;
    }
    break;
    } 
}
public void keyTyped(java.awt.event.KeyEvent e)
{
}
public static void main(String[] args)
{
    new DrawingDemo();
}
}

КЛАССА ЧЕРТЕЖНАЯ ПАНЕЛЬ

import javax.swing.*;
import java.awt.geom.*;
import java.awt.*;
import java.awt.Graphics;

public class DrawingPanel extends JPanel {

long nextSecond = System.currentTimeMillis() + 1000;
int framesInLastSecond = 0;
int framesInCurrentSecond = 0;
int[][] LP= new int[19][3];
  double pos_camx,pos_camy,pos_camz,rot_camx,rot_camy,xpoint,ypoint,zpoint;
  double rot_radx,rot_rady,nclip,xscr,yscr,kx,ky;
  int pxscr,pyscr,nxscr,nyscr,e;



 public void paint(Graphics g)
 {
            LP[0][0] = -1;
        LP[0][1] = -1;
        LP[0][2] = -1;

        LP[1][0] = 1;
        LP[1][1] = -1;
        LP[1][2] = -1;

        LP[2][0] = 1;
        LP[2][1] = 1;
        LP[2][2] = -1;

        LP[3][0] = -1;
        LP[3][1] = 1;
        LP[3][2] = -1;

        LP[4][0] = -1;
        LP[4][1] = -1;
        LP[4][2] = -1;

        LP[5][0] = 1;
        LP[5][1] = 1;
        LP[5][2] = -1;

        LP[6][0] = 1;
        LP[6][1] = 1;
        LP[6][2] = 1;

        LP[7][0] = -1;
        LP[7][1] = 1;
        LP[7][2] = 1;

        LP[8][0] = -1;
        LP[8][1] = -1;
        LP[8][2] = 1;

        LP[9][0] = 1;
        LP[9][1] = -1;
        LP[9][2] = 1;

        LP[10][0] = 1;
        LP[10][1] = 1;
        LP[10][2] = 1;

        LP[11][0] = -1;
        LP[11][1] = -1;
        LP[11][2] = 1;

        LP[12][0] = -1;
        LP[12][1] = -1;
        LP[12][2] = -1;

        LP[13][0] = 1;
        LP[13][1] = -1;
        LP[13][2] = 1;

        LP[14][0] = 1;
        LP[14][1] = -1;
        LP[14][2] = -1;

        LP[15][0] = 1;
        LP[15][1] = 1;
        LP[15][2] = 1;

        LP[16][0] = -1;
        LP[16][1] = 1;
        LP[16][2] = -1;

        LP[17][0] = -1;
        LP[17][1] = 1;
        LP[17][2] = 1;

        LP[18][0] = -1;
        LP[18][1] = -1;
        LP[18][2] = -1; 

 pos_camx = 0;
 pos_camy = 0;
 pos_camz = 0;

 rot_camx = 0;
 rot_camy = 0;
 rot_radx = 3.1415*rot_camx/180;
 rot_rady = 3.1415*rot_camy/180;

 nclip = 0.275;
 kx = 8.52/getWidth();
 ky = 5.46/getHeight();
 super.paint(g);
    Graphics2D g1 = (Graphics2D)g;
    g1.setRenderingHint(RenderingHints.KEY_ANTIALIASING,   RenderingHints.VALUE_ANTIALIAS_ON);
    g.setColor(Color.black);
     xpoint = (double)(LP[0][0])/2;
     ypoint = 20 + (double)(LP[0][1])/2;
     zpoint = (double)(LP[0][2])/2;

     pxscr = (int)(
     ((xpoint - pos_camx)*Math.cos(rot_radx) + (ypoint + pos_camy)*Math.sin(rot_radx))*nclip
     /((ypoint - pos_camy)*Math.cos(rot_radx) + (pos_camx- xpoint)*Math.sin(rot_radx) + 0.0000000012)*100/kx
                  + getWidth()/2);

     pyscr = (int)(
                  getHeight()/2-
     (((ypoint + pos_camy)*Math.sin(rot_rady) + (zpoint - pos_camz)*Math.cos(rot_rady))*nclip
     /((ypoint - pos_camy)*Math.cos(rot_radx) + (pos_camx + xpoint)*Math.sin(rot_radx) + 0.0000000012)*100/ky)
                  );
     for (int i=1; i<19;i++){
            xpoint = (double)(LP[i][0])/2;
            ypoint = 20 + (double)(LP[i][1])/2;
            zpoint = (double)(LP[i][2])/2;

            nxscr = (int)(
         ((xpoint - pos_camx)*Math.cos(rot_radx) + (ypoint + pos_camy)*Math.sin(rot_radx))*nclip
         /((ypoint - pos_camy)*Math.cos(rot_radx)+(pos_camx + xpoint)*Math.sin(rot_radx)+0.0000000012)*100/kx
                         +getWidth()/2);

            nyscr = (int)(
                         getHeight()/2-
         (((ypoint + pos_camy)*Math.sin(rot_rady)+(zpoint - pos_camz)*Math.cos(rot_rady))*nclip
         /((ypoint - pos_camy)*Math.cos(rot_radx)+(pos_camx + xpoint)*Math.sin(rot_radx)+0.0000000012)*100/ky)
                         );
            g1.drawLine(pxscr,pyscr,nxscr,nyscr);

         pxscr = nxscr;
         pyscr = nyscr;
        }
         g.drawString("(" + pxscr + "," + pyscr + ")",20,40);
         long currentTime = System.currentTimeMillis();
  if (currentTime > nextSecond) {
    nextSecond += 1000;
    framesInLastSecond = framesInCurrentSecond;
    framesInCurrentSecond = 0;
  }
 framesInCurrentSecond++;
 g.drawString(framesInLastSecond + " fps", 20, 20);
}

}

2 ответа

Swing - это среда, управляемая событиями. Любая блокировка потока диспетчеризации событий помешает ему начать обрабатывать любые события (например, события мыши или клавиатуры).

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

В то время как JFrame фокусируемый, он содержит JRootPane которая содержит (помимо прочего) панель содержимого, которая содержит ваши DrawingPanel, Любой из них может украсть фокус с кадра в любое время, делая ваш KeyListener бесполезный.

Предпочтительным методом является использование API привязки клавиш

Как правило, вы не рекомендуется переопределять paint, Рисование - очень сложный метод, и вы должны переопределять его, только если вы абсолютно уверены, что это правильно. Предпочтительный метод выполнения пользовательской живописи - переопределить paintComponent метод, как выложено здесь. Наиболее важной причиной этого является то, что этот метод имеет двойную буферизацию, что делает рисование более плавным, и, как правило, вы не будете мешать другим компонентам, которые могут быть на компоненте.

Кроме того, в вашем методе рисования вы устанавливаете положение камеры в 0 что в основном отменяет всю вашу хорошую работу с вашими нефункциональными клавишными слушателями;)

public class DrawingDemo extends JFrame { //implements ActionListener, KeyListener {

    DrawingPanel demo = new DrawingPanel();

    public DrawingDemo() {

        getContentPane().add(demo);
        setVisible(true);
        setSize(1024, 720);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        JPanel p = new JPanel();
        JMenuBar mb = new JMenuBar();
        JMenu file = new JMenu("File");
        JMenu edit = new JMenu("Edit");
        JMenu settings = new JMenu("Settings");
        JMenu help = new JMenu("Help");
        JMenuItem exit = new JMenuItem(">Exit");
        JMenuItem imp = new JMenuItem(">Import");
        JMenuItem exp = new JMenuItem(">Export");
        JMenuItem sav = new JMenuItem(">Save");
        JMenuItem ope = new JMenuItem(">Open");
        file.add(ope);
        file.add(sav);
        file.add(imp);
        file.add(exp);
        file.add(exit);
        mb.add(file);
        mb.add(edit);
        mb.add(settings);
        mb.add(help);
        setJMenuBar(mb);

    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DrawingDemo();
            }
        });
    }

    public class DrawingPanel extends JPanel {

        long nextSecond = System.currentTimeMillis() + 1000;
        int framesInLastSecond = 0;
        int framesInCurrentSecond = 0;
        int[][] LP = new int[19][3];
        double pos_camx, pos_camy, pos_camz, rot_camx, rot_camy, xpoint, ypoint, zpoint;
        double rot_radx, rot_rady, nclip, xscr, yscr, kx, ky;
        int pxscr, pyscr, nxscr, nyscr, e;

        public DrawingPanel() {
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "Move.A");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "Move.D");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "Move.W");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "Move.S");

            ActionMap am = getActionMap();
            am.put("Move.A", new MoveXAction(this, 0.5f));
            am.put("Move.D", new MoveXAction(this, -0.5f));
            am.put("Move.W", new MoveYAction(this, 0.5f));
            am.put("Move.S", new MoveYAction(this, -0.5f));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.

            LP[0][0] = -1;
            LP[0][1] = -1;
            LP[0][2] = -1;

            LP[1][0] = 1;
            LP[1][1] = -1;
            LP[1][2] = -1;

            LP[2][0] = 1;
            LP[2][1] = 1;
            LP[2][2] = -1;

            LP[3][0] = -1;
            LP[3][1] = 1;
            LP[3][2] = -1;

            LP[4][0] = -1;
            LP[4][1] = -1;
            LP[4][2] = -1;

            LP[5][0] = 1;
            LP[5][1] = 1;
            LP[5][2] = -1;

            LP[6][0] = 1;
            LP[6][1] = 1;
            LP[6][2] = 1;

            LP[7][0] = -1;
            LP[7][1] = 1;
            LP[7][2] = 1;

            LP[8][0] = -1;
            LP[8][1] = -1;
            LP[8][2] = 1;

            LP[9][0] = 1;
            LP[9][1] = -1;
            LP[9][2] = 1;

            LP[10][0] = 1;
            LP[10][1] = 1;
            LP[10][2] = 1;

            LP[11][0] = -1;
            LP[11][1] = -1;
            LP[11][2] = 1;

            LP[12][0] = -1;
            LP[12][1] = -1;
            LP[12][2] = -1;

            LP[13][0] = 1;
            LP[13][1] = -1;
            LP[13][2] = 1;

            LP[14][0] = 1;
            LP[14][1] = -1;
            LP[14][2] = -1;

            LP[15][0] = 1;
            LP[15][1] = 1;
            LP[15][2] = 1;

            LP[16][0] = -1;
            LP[16][1] = 1;
            LP[16][2] = -1;

            LP[17][0] = -1;
            LP[17][1] = 1;
            LP[17][2] = 1;

            LP[18][0] = -1;
            LP[18][1] = -1;
            LP[18][2] = -1;

//            pos_camx = 0;
//            pos_camy = 0;
//            pos_camz = 0;

            rot_camx = 0;
            rot_camy = 0;
            rot_radx = 3.1415 * rot_camx / 180;
            rot_rady = 3.1415 * rot_camy / 180;

            nclip = 0.275;
            kx = 8.52 / getWidth();
            ky = 5.46 / getHeight();
            Graphics2D g1 = (Graphics2D) g;
            g1.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g.setColor(Color.black);
            xpoint = (double) (LP[0][0]) / 2;
            ypoint = 20 + (double) (LP[0][1]) / 2;
            zpoint = (double) (LP[0][2]) / 2;

            pxscr = (int) (((xpoint - pos_camx) * Math.cos(rot_radx) + (ypoint + pos_camy) * Math.sin(rot_radx)) * nclip
                    / ((ypoint - pos_camy) * Math.cos(rot_radx) + (pos_camx - xpoint) * Math.sin(rot_radx) + 0.0000000012) * 100 / kx
                    + getWidth() / 2);

            pyscr = (int) (getHeight() / 2
                    - (((ypoint + pos_camy) * Math.sin(rot_rady) + (zpoint - pos_camz) * Math.cos(rot_rady)) * nclip
                    / ((ypoint - pos_camy) * Math.cos(rot_radx) + (pos_camx + xpoint) * Math.sin(rot_radx) + 0.0000000012) * 100 / ky));
            for (int i = 1; i < 19; i++) {
                xpoint = (double) (LP[i][0]) / 2;
                ypoint = 20 + (double) (LP[i][1]) / 2;
                zpoint = (double) (LP[i][2]) / 2;

                nxscr = (int) (((xpoint - pos_camx) * Math.cos(rot_radx) + (ypoint + pos_camy) * Math.sin(rot_radx)) * nclip
                        / ((ypoint - pos_camy) * Math.cos(rot_radx) + (pos_camx + xpoint) * Math.sin(rot_radx) + 0.0000000012) * 100 / kx
                        + getWidth() / 2);

                nyscr = (int) (getHeight() / 2
                        - (((ypoint + pos_camy) * Math.sin(rot_rady) + (zpoint - pos_camz) * Math.cos(rot_rady)) * nclip
                        / ((ypoint - pos_camy) * Math.cos(rot_radx) + (pos_camx + xpoint) * Math.sin(rot_radx) + 0.0000000012) * 100 / ky));
                g1.drawLine(pxscr, pyscr, nxscr, nyscr);

                pxscr = nxscr;
                pyscr = nyscr;
            }
            g.drawString("(" + pxscr + "," + pyscr + ")", 20, 40);
            long currentTime = System.currentTimeMillis();
            if (currentTime > nextSecond) {
                nextSecond += 1000;
                framesInLastSecond = framesInCurrentSecond;
                framesInCurrentSecond = 0;
            }
            framesInCurrentSecond++;
            g.drawString(framesInLastSecond + " fps", 20, 20);
        }
    }

    public class MoveXAction extends AbstractAction {

        private float direction;
        private final DrawingPanel pane;

        private MoveXAction(DrawingPanel pane, float amount) {

            this.direction = amount;
            this.pane = pane;

        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("...x by " + direction);
            pane.pos_camx += direction;
            pane.repaint();
        }

    }

    public class MoveYAction extends AbstractAction {

        private float direction;
        private final DrawingPanel pane;

        private MoveYAction(DrawingPanel pane, float amount) {

            this.direction = amount;
            this.pane = pane;

        }

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("...y by " + direction);
            pane.pos_camy += direction;
            pane.repaint();
        }

    }

}

У меня была быстрая тренировка, и я должен сказать, Ницца;)

Вам нужно перекрасить только если что-то изменилось, и даже тогда, вероятно, не миллион раз в секунду (или что-то еще, что может обработать ваш процессор). так что я бы предложил изменить while(true) в цикл, который ждет немного, или перекрасить в списке ключей (в зависимости от того, что вы хотите, чтобы приложение делало)

и вы реализуете keylistener интерфейс, но вы не добавляете его к зарегистрированным слушателям, поэтому вам нужно this.addKeyListener(this);

JMenuBar не появляется, потому что вы делаете рамку видимой перед добавлением меню. обычно вы хотите сделать окно видимым после инициализации его компонентов. так что ставь setVisible(true); после добавления меню

Другие вопросы по тегам