Fenster während Verbindungsversuch

hesk

Erfahrenes Mitglied
Hallo!

Ich möchte gerne ein Fenster anzeigen während das Programm versucht auf die Datenbank zu connecten.
Wie macht man das am besten?

Ich mach momentan:

Fenster erstellen( extends JFrame )
Connection herstellen
Wenn erfolgreich, dann Fenster.dispose();

Oder ist der Ansatz falsch?
 

Fabio Hellmann

Erfahrenes Mitglied
Hi,

also prinzipiell gibt es dafür wahrscheinlich viele Ansätze und letztenendes auch viele Lösungswege. Ich würde es wahrscheinlich über ein Dialog/JDialog lösen. Auf diesen kann man dann einen 'Cancel'-Button setzen, damit der Verbindungsaufbau abgebrochen werden kann.

Gruß

Fabio
 

hesk

Erfahrenes Mitglied
Ich habs grad auf verschiedene Arten probiert.
Auch mit einem JDialog. Aber dann macht er nicht weiter.
Den JDialog in einern SwingWorker schmeißen sodass er im Hintergrund arbeitet hat auch nicht funktioniert.
 

hesk

Erfahrenes Mitglied
Mein JDialog:

Java:
package heskSystem.zauberperlen.dialogs;

import heskSystem.zauberperlen.objects.GridBagLayoutEditor;

import java.awt.Font;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JDialog;
import javax.swing.JLabel;

import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;

@SuppressWarnings("serial")
public class WaitingDialog extends JDialog
{
    // GridBagConstraints
    @SuppressWarnings("unused")
    private int gridx, gridy, gridwidth, gridheight, fill, anchor, ipadx, ipady;
    private double weightx, weighty;
    @SuppressWarnings("unused")
    private Insets defaultInsets;

    private ResourceMap resourceMap;

    /**
     * Konstruktor Creates the reusable dialog.
     */
    public WaitingDialog(String text)
    {
        super( ( (SingleFrameApplication) Application.getInstance() ).getMainFrame(), true );

        resourceMap = Application.getInstance().getContext().getResourceMap( getClass() );

        initComponent( ( (SingleFrameApplication) Application.getInstance() ).getMainFrame(), text );
    }
    
    /**
     * Statischer Konstruktor
     * @param text
     */
    public static void show( String text )
    {
        WaitingDialog waitingDialog = new WaitingDialog(text);
        waitingDialog.showIt();
    }

    /**
     * Initialisiert die Komponenten
     * 
     * @throws Exception
     */
    public void initComponent( Frame parentFrame, String text )
    {
        //setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
        setUndecorated(true);
        setResizable( false );

        setLayout( new GridBagLayout() );

        // Bild
        GridBagLayoutEditor.setDefaultValuesGB( this );
        JLabel bild = new JLabel( resourceMap.getImageIcon("waiting.icon") );  
        GridBagLayoutEditor.addGB( this, bild, gridx = 0, gridy = 0, 
                                   gridwidth, gridheight, fill = GridBagConstraints.BOTH,
                                   weightx, weighty, anchor, 
                                   new Insets( 20, 20, 20, 20 ) );
        
        // Text
        GridBagLayoutEditor.setDefaultValuesGB( this );
        JLabel labelText = new JLabel( text );
        labelText.setFont( new Font( "Calibri", Font.PLAIN, 15 ) );
        GridBagLayoutEditor.addGB( this, labelText, gridx = 0, gridy = 1, 
                                   gridwidth, gridheight, fill, 
                                   weightx = 1, weighty, anchor,
                                   new Insets( 5, 20, 5, 20 ) );

        pack();
        setLocationRelativeTo( parentFrame );
        
    }
    
    public void showIt()
    {
        setVisible( true );
    }
}

In der DB-Klasse wo ich die Connectino herstelle habe ich einen Task:

Java:
private class Waiting extends Task<Void, Void>
    {
        private WaitingDialog waitingDialog;
        
        public Waiting()
        {
            super(Application.getInstance());
            this.waitingDialog = new WaitingDialog("Verbindung wird hergestellt...");
        }

        @Override
        protected Void doInBackground() throws Exception
        {
            waitingDialog.showIt();
            return null;
        }
        
        /**
         * Abbrechen wurde gedrückt
         */
        @Override
        protected void cancelled()
        {
            waitingDialog.dispose();
        }
    }

Wenn ich nun den Dialog mittels execute aufrufe, wird leider nichts angezeigt.

Java:
Waiting waiting = new Waiting();
waiting.execute();
// Connection wird hergestellt
// Wenn erfolgreich
waiting.cancel(true);
 
S

SE

Das mit einem JDialog zu lösen ist nicht gerade die beste Lösung denn ein JDialog blockiert den kompletten Programmfluss. Der einzige Work-Around ist das Connecten in eine Thread packen , diesen starten und DANN erst den JDialog anzuzeigen. Aber in der Regel braucht man für sowas keine Info abgeben weil sowas normalerweise sehr schnell geschiet ... zumindest wenn man sich an eine grundlegende Sicherheitsregel hält : User nur von localhost akzeptieren.
 

hesk

Erfahrenes Mitglied
Es wird eine Connection zu einer Mysql-Datenbank über das Internet gemacht. Und das dauert manchmal 10-20 sec. Für diese Zeit würde ich gerne eine Meldung ausgeben.

Warum einen extra Thread für die Connection?

So mache ich die Connection. Davor würde ich gern das Fenster einblenden. Nach der Funktion wieder ausblenden.

Java:
private void openConnection( String url, String database, String user, String password ) throws SQLException
    {
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setURL( url + database );
        mysqlDataSource.setUser( user );
        mysqlDataSource.setPassword( password );
        
        dataSource = mysqlDataSource;
        
        simpleJdbcTemplate = new SimpleJdbcTemplate( dataSource );
        
        // Die Verbindung testen
        Connection connection = dataSource.getConnection();
        connection.close();
    }

Und jetzt bräuchte ich halt Anregung wie man sowas am besten löst.
 

hesk

Erfahrenes Mitglied
Wenn ich den JDialog mittels

Java:
setModalityType(Dialog.ModalityType.MODELESS);

setze, dann wird zwar das Fenster angezeigt, aber ohne Inhalt.
 

Anhänge

  • LeererJDialog.JPG
    LeererJDialog.JPG
    5,1 KB · Aufrufe: 5
S

SE

Das wäre für mich schon ein zu großes Sicherheitsrisiko Verbindungen dierekt von außen zuzulassen. Ich würde hier eine Proxy-Anwendung auf dem Server installieren der neben einer zusätzlichen Sicherung auch die Angriffsmöglichkeiten verringert da man erstmal diesen Proxy knacken müsste.

Warum ein extra Thread ? Weil der JDialog , egal ob Model oder nicht , den Programmfluss total blockiert. Darum muss entweder der Caller des JDialogs in einem Thread laufen oder die Verbindung zur Datenbank. Am besten wäre natürlich beide in einzelne Threads auslagern und den Rest der GUI über die modalität zu sperren.

Eine Verbindung die 10-20sec dauert ? Ist das ohne Modifikation überhaupt so einfach möglich ? Ich dachte nach 5sec kommt das SocketTimeout.
 

Neue Beiträge