AWT-Alternative gesucht - Problem mit AWT+JDialogPane

CodeKrieger

Mitglied
Hallo liebe Community,

ich weiß ja, dass man nicht Swing und AWT zusammen benutztn soll. Aber ich weiß leider keine Alternative dafür.

Doch leider führt folgender Code
Java:
public void userInteraction(){
        if(userInteractionCounter % 2 == 0){
                    String msg = JOptionPane.showInputDialog(_vc, 
                    "Enter a message for the user interaction", 
                    "Enter Message", 
                    JOptionPane.QUESTION_MESSAGE);	
            newStage(userInteractionCounter, "UserInteractionBegin", msg);
            userInteractionCounter++;
            forceSyncPointCreation = true;
            System.out.println("Begin");
            syncCenter();
        }
        else { 
            syncCenter();
            newStage(userInteractionCounter, "UserInteractionEnd", "");
            forceSyncPointCreation = false;
            userInteractionCounter++;
            correctDelay = true;
            System.out.println("End");
            idleTime = 0; 
        }
        
    }
Gibt mir folgendes aus
Begin
End
Begin

was natürlich unerwünscht ist-.

Kommentiere ich in der oberen Hälfte das JOptionPane aus (uns rufe newStage mit "") auf, dann läuft es korrekt:
Begin
End
Die Methode wird also aus irgendeinem Grund nochmal aufgerufen. Wobei ich dazu sagen muss, dass sie durch eine Tastenkombination ausgelöst wird. Möglicherweise wird auch diese Tastenkombination nochmal wiederholt. Von mir gedrückt wurde der Shortcut genau 2x (Begin und end).

Hat jemand eine Idee, wie man das verhindern kann? Oder wie könnte ich etwas ähnliches nur mit AWT erreichen?

Danke schonmal im Vorraus.

Edit: Habe den Titel mal etwas aussagekräftiger gemacht.
 
Zuletzt bearbeitet:
Warum benutzt du dann nicht gleich Swing? Dein Code sagt leider nichts aus, außer dass die Variable _vc schlecht benannt ist. Der Aufrufer selbst wäre wohl wichtiger.
 
Geht nicht, das ist ein riesiges Projekt, ich mache hier "nur" meine Masterarbeit. Kann also unmöglich alles auf Swing umstellen.

_vc ist ein VncCanvas-Object, welches Canvas erweitert.

Mit dem Aufrufer selbst könnt ihr auch nichts anfangen. Das ist alles sehr speziell.

Gibts denn in AWT eine Methode, das zu realisieren?
 
Aus der Hauptklasse VncViewer
Java:
public void startUserInteractionMode(){
      if(vc.getState() == 1){
          inputRecorder.userInteraction();
        vc.saveMousePos();
        pauseRecording(false);
        
      }
      
  }
  public void stopUserInteractionMode(){
      if(vc.getState() == 3){
          vc.correctMousePos();
          resumeRecording();
          inputRecorder.userInteraction();
          
      }
  }
Aus der Methode processCtrlAltCommands (mouseEvent evt, Set<Integer> pressed), die die Tastenkombinationen verarbeitet. Die Tastenkombination hier ist Strg-Alt-I

Java:
if(pressed.contains(KeyEvent.VK_I)){
            if(vc.getState() == 1){
                startUserInteractionMode();
            }
            else if(vc.getState() == 3) {
                
                stopUserInteractionMode();
            }

Und diese Methode wird wiederum vom KeyListener aufgerufen.

Glaub aber nicht, dass ihr damit was anfangen könnt. Ich wollte eher von dem Punkt ausgehen, dass es mit JOptionPane nicht geht, ohne aber schon. Das deutet doch darauf hin, dass es offenbar ein Problem zwischen Swing und AWT gibt, oder? Ohne das JOptionPane wird der Tastendruck korrekt verarbeitet und danach verworfen. Mit klappt das irgendwie nicht. Der Tastendruck wird nicht gelöscht.
 
Zuletzt bearbeitet:
Bastel dir doch selber einen Dialog der eine Eingabemaske liefert, in AWT. JOptionPane is ja nur eine Convenience Klasse. Vielleicht musst du aber auch nur deinen Dialog schon vor der Funktion userInteraction aufrufen, das kann man ohne weiteren Einblick in die Materie nicht sagen.
 
Falls es nur der KeyListener ist, das funktioniert bei mir problemlos:

Java:
public static void main(String[] args) {
	Frame frame = new Frame();
	frame.addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	});
	frame.addKeyListener(new KeyAdapter() {
		public void keyPressed(KeyEvent e) {
			if(e.getKeyCode() == KeyEvent.VK_ENTER) {
				String msg = JOptionPane.showInputDialog(null, "Test", null,
						JOptionPane.QUESTION_MESSAGE);
				System.out.println(msg);
			}
		}
	});
	frame.setSize(400, 400);
	frame.setVisible(true);
}

Falls du aber wirklich auf JOptionPanes verzichten willst, gäbe es die Möglichkeit:

Java:
public static void main(String[] args) {
	frame = new Frame();
	frame.addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
			System.exit(0);
		}
	});
	frame.addKeyListener(new KeyAdapter() {
		public void keyPressed(KeyEvent e) {
			if(e.getKeyCode() == KeyEvent.VK_ENTER) {
				String s = showQuestion(frame, "Please input your choose.", null);
				System.out.println(s);
			}
		}
	});
	frame.setSize(400, 400);
	frame.setVisible(true);
}
private static String showQuestion(Frame parent, String msg, String title) {
	final Dialog dialog = new Dialog(parent, title, true);
	dialog.addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
			dialog.dispose();
		}
	});
	dialog.add(new JLabel(msg), BorderLayout.NORTH);
	
	Panel inputPanel = new Panel(new BorderLayout());
	dialog.add(inputPanel, BorderLayout.CENTER);
	
	inputPanel.add(new Label("Input:"), BorderLayout.WEST);
	
	TextField field = new TextField();
	field.addKeyListener(new KeyAdapter() {
		public void keyPressed(KeyEvent e) {
			int keyCode = e.getKeyCode();
			if(keyCode == KeyEvent.VK_ENTER || keyCode == KeyEvent.VK_ESCAPE) {
				dialog.dispose();
			}
		}
	});
	inputPanel.add(field, BorderLayout.CENTER);
	
	Panel buttonPanel = new Panel(new FlowLayout(FlowLayout.CENTER));
	dialog.add(buttonPanel, BorderLayout.SOUTH);
	
	Button okButton = new Button("OK");
	okButton.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			dialog.dispose();
		}
	});
	buttonPanel.add(okButton);
	
	
	dialog.pack();
	dialog.setLocationRelativeTo(dialog.getParent());
	dialog.setVisible(true);
	
	return(field.getText());
}
 
Ok, also grundsätzlich scheint das schon zu gehen. Die Frage ist jetzt also warum es bei mir nicht geht. Meine Vermutung ist, dass das JOptionPane den Listener an sich reisst und danach nicht korrekt zurücksetzt. Dadurch wird möglicherweise das gesamte Programm gestört, weil es darauf ausgelegt ist Benutzerinteraktionen zu jeder Zeit zu verarbeiten. Muss da morgen mal weiterexperimenteiren 🙂
 
Weitere Nachforschungen haben ergeben:

mit dem JDialogPane passiert folgendes
1. Strg-Alt-I -> Meldung erscheint -> korrekt
2. Strg-Alt -> Modus wird beendet, OBWOHL kein "I" gedrückt wurde -> Falsch!!!

Für die Verarbeitung der Tastendrücke benutze ich folgende Funktionen.
Java:
public void keyPressed(KeyEvent evt) {   
    pressed.add(evt.getKeyCode());
    if (!inputBlocked) processLocalKeyEvent(evt);
    evt.consume();
       
  }
  @Override
  public void keyReleased(KeyEvent evt) {        
    pressed.remove(evt.getKeyCode());
    if (!inputBlocked) processLocalKeyEvent(evt);
    evt.consume();        
  }
  @Override
  public void keyTyped(KeyEvent evt) {
    evt.consume();
  }

pressed wird an die Funktion ProcessCtrlAltCommands() übergeben, wenn es Strg und Alt enthält. Inm obigen Fall 2 enthält pressed aber auch das I obwohl dieses nicht gedrückt wurde.

Das wirklich seltsame ist, dass ohne den JDialog alles einwandfrei funktioniert, Am Listener kann es ja eigentlich auch nicht liegen, denn wenn der Listener nicht korrekt zurückgegeben wird, dann würde ja garnichts passieren, wenn ich Strg-Alt-drücke. Ich kann das System aber ganz normal bedienen. Nur wenn ich Strg-Alt drücke, kommt diese Fehlfunktion zu Tage.

Ich habe auch versucht, das ganze vor dem Aufruf des JDialogPane in einen fest definierten Pause-Zustand zu versetzen, in dem es keine Eingaben erlaubt. Aber das hilft auch nix :-(
Any Ideas?

Edit: Nachdem ich das hier geschrieben hatte wurde es mir klar: Die DialogBox verhindert, dass keyReleased ausgelöst wird. Gefixt habe ich das etwas unschön durch eine Methode clearPressed(). Hauptsache es geht jetzt endlich!
 
Zuletzt bearbeitet:

Zurück
Oben