Swing JTextfield hängt sich bei Eingabe auf

chaostheory

Bekanntes Mitglied
Hallo,
für ein 2D-Spiel habe ich einen Cheat-Modus eingebaut. Um diesen zu aktivieren, klickt man in die linke obere Ecke und muss beim dann erscheinenden JPasswordField das korrekte Passwort eingeben.

Das klappt so weit ganz gut, nur hängt sich das Programm auf, wenn man etwas im Feld eingibt.
Der Prozess läuft noch normal und es werden auch keine Exceptions ausgeworfen, aber nichts reagiert mehr und das Spiel bleibt auch stehen.

Ein einziges Mal wurde ein NullPointer auf diese Zeile ausgeworfen:
Java:
frame.getLayeredPane().paintComponents(graphics);

Ich benutze KeyBindings auf das JPanel, sodass Tastatureingaben unabhängig vom Fokus immer erkannt werden. Alle registrierten Tasten funktionieren, aber sobald ich eine andere im Passwortfeld drücke, bleibt das Programm stehen und ich kann nichts mehr machen.

Ich benutze auch keinen Layout-Manager, könnte das damit zusammenhängen?
Ja, ich weiß, dass man das nicht machen soll, aber ich habe nicht mehr sonderlich viel Zeit, mich Layout zu beschäftigen.

Hier werden alle Komponenten erstellt und auf das JPanel gelegt (Alles außer dem Passwortfeld habe ich raus gekürzt)
Java:
JPasswordField devPre_passwordField = new JPasswordField(10);

		devPre_passwordField.setBounds(10, 10, 120, 25);

		devPre_passwordField.addActionListener(new ActionListener() {
			char[] correctPassword = {'d', 'e', 'v', 'e', 'l', 'o', 'p', 'e', 'r'};
			@Override
			public void actionPerformed(ActionEvent event) {
				char[] input = devPre_passwordField.getPassword();
				if(input.length == correctPassword.length && input.equals(correctPassword)) {
					main.setStatus(GameStatus.DEV_MAIN);
				}else {
					devPre_passwordField.setText("");
					main.setStatus(GameStatus.GAME);
				}
			}
		});
		
		hideAll();
		showMainMenu();
		panel.add(devPre_passwordField);
 
Code:
input.equals(correctPassword)
wird übrigens immer
Code:
false
liefern, weil es auf Identität prüft. Nutz stattdessen Arrays.equals().
 
Code:
input.equals(correctPassword)
wird übrigens immer
Code:
false
liefern, weil es auf Identität prüft. Nutz stattdessen Arrays.equals().
Stimmt, danke für den Hinweis.

Woher hast Du das Graphics Objekt und warum rufst Du die paintComponents() auf? Diese Methode(n) sollte man nicht selbst aufrufen.
Vom DoubleBuffering. Zeichne ich die Komponenten nicht jedes mal neu, werden sie vom Spiel verdeckt.
Hier mal die gesamte draw-Methode:
Java:
public void draw() {
		Graphics2D graphics = null;
		JFrame frame = screenHandler.getFrame();
		BufferStrategy bs = frame.getBufferStrategy();
        try {

            graphics = (Graphics2D) bs.getDrawGraphics();

            switch(main.getStatus()) {
			case MENU_MAIN:		drawMainMenu(graphics); break;
			case MENU_GAME:		drawGameMenu(graphics); break;
			case GAME:			drawGame(graphics); break;
			case LEVELCHANGE:	drawLevelChange(graphics); break;
			case SCORE:			drawScore(graphics); break;
		}

            graphics.translate(frame.getInsets().left, frame.getInsets().top);
            frame.getLayeredPane().paintComponents(graphics);

            if (!bs.contentsLost())
                bs.show();

        } catch (final IllegalStateException e) {

        } finally {

            if (graphics != null)
                graphics.dispose();

        }

        Toolkit.getDefaultToolkit().sync();

        Thread.yield();
	}

Gerade habe ich wieder eine Fehlermeldung bekommen, als das Feld sichtbar gesetzt wurde:
Code:
Exception in thread "Thread-4" java.lang.NullPointerException
	at javax.swing.text.PlainView.getPreferredSpan(Unknown Source)
	at javax.swing.text.FieldView.getPreferredSpan(Unknown Source)
	at javax.swing.text.PasswordView.getPreferredSpan(Unknown Source)
	at javax.swing.text.FieldView.adjustAllocation(Unknown Source)
	at javax.swing.text.FieldView.adjustPaintRegion(Unknown Source)
	at javax.swing.text.PlainView.paint(Unknown Source)
	at javax.swing.text.FieldView.paint(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI$RootView.paint(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
	at javax.swing.plaf.basic.BasicTextUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at java.awt.Component.lightweightPaint(Unknown Source)
	at java.awt.Container.lightweightPaint(Unknown Source)
	at java.awt.GraphicsCallback$PeerPaintCallback.run(Unknown Source)
	at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
	at java.awt.Component.paintAll(Unknown Source)
	at java.awt.GraphicsCallback$PaintAllCallback.run(Unknown Source)
	at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
	at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
	at java.awt.Container.paintComponents(Unknown Source)
	at me.gschelter.bubbletrouble.manager.DrawManager.draw(DrawManager.java:54)
	at me.gschelter.bubbletrouble.thread.DrawThread.run(DrawThread.java:17)
	at java.lang.Thread.run(Unknown Source)
 

Ich habe noch mal einige Tests gemacht und es ist doch mehr oder weniger das gleiche Problem.
Es liegt definitiv an dieser Zeile:
Java:
frame.getLayeredPane().paintComponents(graphics);
Das Problem ist nur, dass ohne diese Zeile das Passwortfeld gar nicht angezeigt wird und keine einzige Methode, weder in den Komponenten, noch dem JPanel oder dem JFrame, das Problem behebt.
 

Zurück
Oben