JDesktopPane bei Button-Klick anzeigen geht nicht

Studdi23

Mitglied
Hallo zusammen,

ich habe ein JDesktopPane in dem ein JInternalframe gepackt ist welches wiederum ein JLabel mit einfachem Text enthält. Das ganze soll beim Klick auf einen Button innerhalb eines JFrames angezeigt werden, bevor eine Klasse aufgerufen wird, die Tabellendaten aus einer Datenbank ließt. Die JDesktopPane-Komponente soll in der Ebene alle anderen Komponenten des JFrame überdecken, was ich mit der Methode "setComponentZOrder" auch hinbekommen hab. Gleichzeitig wird das JFrame mit "setEnabled" deaktiviert, damit der Benutzer während die Datenbankverbindung aufgebaut wird keine anderen Aktionen ausführen kann. Das JLabel zeigt einfach nur einen Hinweis das gerade eine Verbindung hergestellt wird. Ein- und Ausblenden des JDesktopPane wird mit "setVisible()" realisiert. Solange ich den Auruf der Klasse für die Db-Connection auskommentiert lasse klappt auch alles einwandfrei. Ich denke das es etwas mit dem Zustand des Buttons zu tun hat. Solange dieser auf gedrückt steht, können keine bestehenden oder hinzugefügte Komponenten neu gerendered werden. Liege ich in der Annahme richtig? Wie kann ich das Problem umgehen?

Hier ein paar Code-Schnipsel. [EDIT]Hab weiter unten auch noch ein Bild angehängt:[/EDIT]

Java:
private JButton getJButton() {
		JButton jButton = new JButton();
		jButton.setBackground(Color.LIGHT_GRAY);
		jButton.setText("Execute");
		jButton.setToolTipText("SQL Befehl ausführen");
		jButton.setOpaque(true);
		jButton.setFocusable(false);
		jButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				String location = locationInput.getText();
				String statement = selectInput.getText();
				if (statement.length() == 0 || statement.equals(JTA_INIT))
					return;
				if (location.length() != 0)
					infoBean.setPersistence_unit_name(location);
				infoBean.setSql_statement(statement);
				showConnectionLabel(true); //Hier soll das JDesktopPane eingeblendet werden
				new DatabaseConnection(infoBean); //Daten werden geholt
				showConnectionLabel(false); //wieder ausblenden
				if (infoBean.getMessages() != null)
					JOptionPane.showMessageDialog(jContentPane,
							infoBean.getMessages());
				dbData.setModel(new AmazonTableModel(infoBean.getResult(),
						columnNames));
			}
		});
		return jButton;
	}

Java:
private void showConnectionLabel(boolean flag) {
		if (flag) {
			this.setEnabled(false);
			connectLabel.setVisible(true);
		} else {
			this.setEnabled(true);
			connectLabel.setVisible(false);
		}
	}

Java:
private JDesktopPane getJDesktopPane() {
		JDesktopPane jDesktopPane = new JDesktopPane();
		jDesktopPane.setPreferredSize(new Dimension(250, 150));
		JInternalFrame jInternalFrame = new JInternalFrame("");
		jInternalFrame.setResizable(false);
		jInternalFrame.setSize(250, 150);
		// jInternalFrame.putClientProperty("JInternalFrame.isPalette",
		// Boolean.TRUE);
		jInternalFrame.setOpaque(true);
		((BasicInternalFrameUI) jInternalFrame.getUI()).setNorthPane(null);
		JLabel jLabel = new JLabel();
		jLabel.setText("Datenbankverbindung wird hergestellt...\n");
		jLabel.setForeground(Color.BLUE);
		jLabel.setFont(new Font("Arial", Font.BOLD, 12));
		jInternalFrame.add(jLabel);
		jInternalFrame.setVisible(true);
		jDesktopPane.add(jInternalFrame);
		jDesktopPane.setVisible(false);
		jDesktopPane.setFocusable(false);
		return jDesktopPane;
	}
 

Anhänge

  • gui.jpg
    gui.jpg
    75,8 KB · Aufrufe: 31
Zuletzt bearbeitet:
Die Datenbankabfrage muss in einem separaten Thread ablaufen, sonst wird der EDT und somit das Zeichen des UI solange blockiert bis die Datenbankabfrage abgeschlossen ist.

Wenn ich das richtig verstehe willst Du mit Deinem Konstrukt aus JLayeredPane, JDesktopPane und JInternalFrame Deine Oberfläche solange "Sperren". Da gibt es bessere Varianten:
- einzelne Elemente gezielt deaktivieren
- mittels CardLayout eine andere Komponente anzeigen
- blockieren mittels einer GlassPane (JFrame.setGlassPane(Component c))
 
Hi und danke erstmal für die Antwort,

woher weiß ich denn wann die Datenbankabfrage im zweiten Thread beendet ist, damit ich die UI-Komponente wieder ausblenden und die interaktiven Elemente wieder freigeben kann? Hab gedacht
Swing läuft generell synchron und blockiert grundsätzlich jede weitere Operation.
Hab mir aber schon gedacht das ich die Applikation in einem separaten Thread ausführen muß. Irgendwelche Anregungen wie ich das am besten umsetzen kann?

Ein GlassPane wäre sicherlich die elegantere Lösung gewesen, aber ich wollte zunächst einmal austesten ob es überhaupt funktioniert bevor ich mir weiter Gedanken über das Layout mache 🙂

Gruß
Mario
 
So das ging jetzt schneller als erwartet. Hab zwischenzeitlich eine Library für asynchrones Swing gefunden. Mit folgender Implementierung funktionierts hervorragend (Just 4 Info):

Java:
@Override
			public void actionPerformed(ActionEvent e) {
				String location = locationInput.getText();
				String statement = selectInput.getText();
				if (statement.length() == 0 || statement.equals(JTA_INIT))
					return;
				if (location.length() != 0)
					infoBean.setPersistence_unit_name(location);
				infoBean.setSql_statement(statement);
				showConnectionLabel(true);
				AsynchronousOperation<Object> callback = new AsynchronousOperation<Object>(){

					@Override
					protected Object performOperation() throws Exception {
						showConnectionLabel(true);
						new DatabaseConnection(infoBean);
						return null;
					}
					
					@Override
					protected void onComplete()
					{
						showConnectionLabel(false);
					}

					@Override
					protected void onSuccess(Object result){
						dbData.setModel(new AmazonTableModel(infoBean.getResult(),columnNames));
						if (infoBean.getMessages() != null)
							JOptionPane.showMessageDialog(jContentPane,
									infoBean.getMessages());
					}
				};
				SwingUtilities.invokeLater(callback);
			}
		});
		return jButton;
	}

:toll:
 

Neue Themen


Zurück
Oben