Alternative zu JoptionPane

fleckdalm

Bekanntes Mitglied
Ist es möglich statt einer JOptionPane einfach kurz ein transparent schwarzes rechteck mit text aufscheinen zu lassen? Also das man nichts bestätigen braucht und so. Falls das jemand kennt ich meine so ähnlich wie bei android diese informationen.

Danke, mfg Fleckdalm
 
Ich würde solche Informationen eher auf der Glass Pane des JFrames anzeigen.
Eine Alternative zu JOptionPane wäre ein modaler JDialog.


Hi,
lässt sich ein popup überhaupt noch sauber mit einem modalem dialog realisieren?
Er will ja offenbar, dass es sich von alleine schließt.
Ich hab das irgendwo auch mal versucht und meine mich zu erinnern, dass es ziemlich hässlich war am ende (wollte aber unbedingt was modales um eingaben zu sperren 😀)
Gruß
 
Hi,
lässt sich ein popup überhaupt noch sauber mit einem modalem dialog realisieren?
Er will ja offenbar, dass es sich von alleine schließt.
Ich hab das irgendwo auch mal versucht und meine mich zu erinnern, dass es ziemlich hässlich war am ende (wollte aber unbedingt was modales um eingaben zu sperren 😀)
Gruß

Mein Favorit ist, wie gesagt, sowas auf der Glass Pane darzustellen. Mit nem modalem Dialog ginge das auch. Man muss nur beachten, dass das sichtbar machen des Dialogs, den akutellen Thread blockiert ;-)

So q&d könnte man das wie folgt machen, wobei ich das in einem "echten" Programm so nicht einsetzen würde:
Java:
JFrame frame = new JFrame();
frame.setBounds(0, 0, 300, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
final JDialog dialog = new JDialog(frame, true);
dialog.setUndecorated(true);
final JLabel label = new JLabel("", JLabel.CENTER);
label.setOpaque(true);
label.setBackground(Color.BLUE);
dialog.add(label);
dialog.setSize(frame.getWidth()-20, 100);
dialog.setLocationRelativeTo(frame);
new Thread(new Runnable() {
	public void run() {
		int count = 10;
		for (int i=0; i<=count; i++) {
			label.setText("Closing in " + (count-i));
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		dialog.dispose();
	}
}).start();
dialog.setVisible(true);
 
Ich hatte da auch mal was gemacht, vllt suchst du sowas, damit kannst du das gesamte Frame sperren:

Java:
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
public class LockableJFrame extends JFrame {
 
    private LockPane lockPane;
 
    public LockableJFrame() {
        super();
        setupGlassPane();
    }
 
    public LockableJFrame(String title) {
        super(title);
        setupGlassPane();
    }
 
    private void setupGlassPane() {
        this.lockPane = new LockPane();
        setGlassPane(lockPane);
    }
 
    /**
     * Must be called on EDT! Locks this frame so that user events are not
     * handled, and puts a transparent layer on the frame to show the user that
     * the frame is disabled.
     */
    public void lock() {
        this.lock(null);
    }
 
    /**
     * Must be called on EDT! Locks this frame so that user events are not
     * handled, and puts a transparent layer on the frame to show the user that
     * the frame is disabled. In addition, a message is displayed.
     * 
     * @param msg
     *            the message to display.
     */
    public void lock(String msg) {
        this.setEnabled(false);
        setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        LockPane lockPane = (LockPane) getGlassPane();
        lockPane.setMsg(msg);
        lockPane.setVisible(true);
        lockPane.requestFocusInWindow();
    }
 
    /**
     * Must be called on EDT! Unlocks the frame.
     */
    public void unlock() {
        getGlassPane().setVisible(false);
        this.setEnabled(true);
        setCursor(Cursor.getDefaultCursor());
    }
 
    public void setLockAppearance(Color backgrndColor, Color msgColor,
            Font msgFont) {
        lockPane.setBackground(backgrndColor);
        lockPane.setMsgColor(msgColor);
        lockPane.setMsgFont(msgFont);
    }
 
    private class LockPane extends JPanel implements KeyListener {
 
        private String msg;
        private Font msgFont;
        private Color msgColor;
 
        public LockPane() {
            setOpaque(false);
            setFocusTraversalKeysEnabled(false);
            loadDefaultAppearance();
                        addKeyListener(this);
        }
 
        private void loadDefaultAppearance() {
            setBackground(new Color(100, 100, 150, 100));
            msgFont = new Font("SansSerif", Font.PLAIN, 14);
            msgColor = Color.WHITE;
        }
 
        public void setMsg(String msg) {
            this.msg = msg;
        }
 
        public void setMsgColor(Color msgColor) {
            this.msgColor = msgColor;
        }
 
        public void setMsgFont(Font msgFont) {
            this.msgFont = msgFont;
        }
 
        /*
         * Returns the position of a String within this component so that it is
         * centered both horizontally and vertically.
         */
        private Point getCenter(String s, FontMetrics m, int width, int height) {
            int x = (width - m.stringWidth(s)) / 2;
            int y = (height - m.getHeight()) / 2 + m.getAscent();
            Point center = new Point(x, y);
            return center;
        }
 
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            int width = getWidth();
            int height = getHeight();
            g.setColor(getBackground());
            g.fillRect(0, 0, width, height);
            if (msg != null) {
                // calculate positions
                g.setFont(msgFont);
                FontMetrics m = g.getFontMetrics();
                Point msgCenter = getCenter(msg, m, width, height);
                Point boxPos = new Point(msgCenter.x - 10, msgCenter.y
                        - m.getAscent() - 10);
 
                // draw message box
                Color backgrnd = getBackground();
                int red = backgrnd.getRed();
                int green = backgrnd.getGreen();
                int blue = backgrnd.getBlue();
                int alpha = backgrnd.getAlpha();
                g.setColor(new Color(red, green, blue,
                        alpha <= 205 ? alpha + 50 : 255));
                g.fillRoundRect(boxPos.x, boxPos.y, m.stringWidth(msg) + 20, m
                        .getHeight() + 20, 10, 10);
                g.setColor(msgColor);
                g.drawRoundRect(boxPos.x, boxPos.y, m.stringWidth(msg) + 20, m
                        .getHeight() + 20, 10, 10);
 
                // draw message text
                g.setColor(msgColor);
                g.drawString(msg, msgCenter.x, msgCenter.y);
            }
        }
 
        @Override
        public void keyPressed(KeyEvent e) {
            e.consume();
        }
 
        @Override
        public void keyReleased(KeyEvent e) {
            e.consume();
        }
 
        @Override
        public void keyTyped(KeyEvent e) {
            e.consume();
        }
    }
}

Ein Beispiel wie man's nutzt:

Java:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
 
import javax.swing.JButton;
import javax.swing.JFrame;
 
public class LockableJFrameTest {
 
    public static void main(String[] args) {
 
        final LockableJFrame lockFrame = new LockableJFrame(
                "LockableJFrameTest");
        lockFrame.setLockAppearance(new Color(255, 150, 150, 100), Color.WHITE,
                new Font("Arial", Font.BOLD, 22));
        lockFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lockFrame.setSize(500, 500);
 
        // show and LOCK
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                lockFrame.setVisible(true);
                lockFrame.lock("Loading elements...");
            }
        });
 
        // ...
        doSomeStuff(lockFrame);
 
        // UNLOCK
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                lockFrame.unlock();
            }
        });
    }
 
    private static void doSomeStuff(final JFrame f) {
        f.setLayout(new FlowLayout());
        for (int i = 0; i <= 359; i++) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JButton b = new JButton();
                    b.setSize(2, 2);
                    f.add(b);
                    f.validate();
                }
            });
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 
Danke für eure antworten!
@Michael, Danke, aber das ist nicht genau das was ich mir vorgestellt habe
@hdi Danke, das entspricht schon eher meinen Vorstellungen, es ist nur das problem das ich nicht ganz verstehe wie es funktioniert:-( es geht mir dabei aber vor allem ums verstehen da das so eine art Übungsprogramm ist damit ich java einfach besser lerne. Deshalb, könntest du mir bitte erklären wie genau das funktioniert, und wie ich es auf einem Fenster für zb. 3. sec. einblenden könnte? Es schaut nämlich echt cool aus!

Danke, mfg Fleckdalm
 
Schau ins Beispiel, das kannst du so übernehmen:

Java:
  // LOCK
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                lockFrame.lock("Please wait...");
            }
        });
 
        // ... 3 Sekunden warten:
        Thread.sleep(3000); // achtung schmeißt exception!
 
        // UNLOCK
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                lockFrame.unlock();
            }
        });

Es geht jetzt zuweit das mit der EventQueue und invokeLater usw alles zu erklären, bzw. dazu hab ich grad weder Zeit noch Lust, das lässt sich nicht in einem Satz sagen. Google mal etwas nach "Event Dispatcher Thread".
 

Zurück
Oben