Fenstergröße variiert bei JDialog.pack()-Aufruf

  • Themenstarter Themenstarter BigBaer
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
B

BigBaer

Gast
Hallo zusammen,

habe folgende beiden Klassen geschrieben und will nun über "Hilfe" im "Datei"-Menü mit dem ActionListener einen JDialog aufrufen, der einen Hilfetext im HTML-Format aus der Datei "Hilfe.htm" anzeigt. Dies funktioniert, außer, dass nach dem Start der Anwendung oft beim ersten, manchmal auch beim zweiten Aufruf von "Hilfe" das öffnende JDialog-Fenster minimal groß ist und beim zweiten bzw. dritten und den folgenden Malen die korrekte Größe besitzt, so dass der Inhalt auch in seiner Gesamtheit lesbar ist. Habe ich da was falsch gemacht? Wie kann man dieses Problem am besten beheben?


1.
Code:
package battleship;

import java.awt.BorderLayout;
import javax.swing.*;

public class BattleShip {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		// Action Listener for menu
		MyActionListener myActionListener = new MyActionListener();		
		
		// menu items				
	    JMenuItem menuItemHilfe = new JMenuItem("Hilfe");
	    menuItemHilfe.setActionCommand("help");
	    menuItemHilfe.addActionListener(myActionListener);
		
	    JMenuItem menuItemBeenden = new JMenuItem("Beenden");
	    menuItemBeenden.setActionCommand("exit");
	    menuItemBeenden.addActionListener(myActionListener);
	    
	    // main menu "Datei"
	    JMenu fileMenu = new JMenu("Datei");
	    fileMenu.add(menuItemHilfe);	    
	    fileMenu.addSeparator();
	    fileMenu.add(menuItemBeenden);
	    
		// Menu-Bar
		JMenuBar menuBar = new JMenuBar();			    
	    menuBar.add(fileMenu);
	    
		// main window
		JFrame frame = new JFrame("BattleShip V1.0");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(200, 200);
	    frame.setLayout(new BorderLayout());
	    frame.add(menuBar,BorderLayout.NORTH);	    
	    frame.setVisible(true);
	}	
}

2.
Code:
package battleship;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;;

public class MyActionListener implements ActionListener {
	
	@Override 
	public void actionPerformed(ActionEvent ae) {
		if (ae.getActionCommand().equals("exit")) {
			System.out.println("Es wurde \"Beenden\" über das Datei-Menu aufgerufen.");
			System.exit(0);
		}
		
		if (ae.getActionCommand().equals("help")) {
			System.out.println("Die \"Hilfe\" aus dem Datei-Menu wurde aufgerufen.");				
			
			JEditorPane helpText = new JEditorPane();
			helpText.setEditable(false);	
						
			try {
				helpText.setPage(new File("hilfe.htm").toURI().toURL());
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}					    
			
			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setViewportView(helpText);
		
			JButton closeButton = new JButton("Hilfe schließen");
			closeButton.addActionListener(new ActionListener() {
				@Override public void actionPerformed(ActionEvent ae) {
					getTopLevelWindow(ae.getSource()).dispose();
				}
			});
			
			JDialog helpDialog = new JDialog((JFrame)getTopLevelWindow(ae.getSource()),"Hilfe",true);
			helpDialog.setResizable(false);								
			helpDialog.setLayout(new BorderLayout());
			helpDialog.add(scrollPane);
			helpDialog.add(closeButton,BorderLayout.SOUTH);
			helpDialog.pack();
			helpDialog.setVisible(true);						
		}
	}

	private Window getTopLevelWindow(Object o) {
		return (Window)(((JComponent)o).getTopLevelAncestor());
	}	
}
 
Mach mal statt pack() einen setSize(..). Beispiel:
Code:
helpDialog.setSize(600, 500);
 
danke, aber das hilft nur bedingt. Da ich ja die Fenstergröße dynamisch an den jeweils in der Hilfe-Datei gespeicherten Inhalt anpassen möchte. Es beantwortet auch die Frage nicht, warum sich die Funktion bei mehreren Aufrufen hintereinander unterschiedlich verhält. Weißt Du hierzu vielleicht Näheres?
 
Das wäre möglich. Gibt es eine Möglichkeit, das Programm dann so lange pausieren zu lassen, bis die Seite vollständig geladen wurde? (Damit meine ich nicht ungenaue Möglichkeiten, wie Thread.sleep(nn), sondern eher eine Abfrage, wann das Laden der Seite beendet wurde).
 
BigBaer hat gesagt.:
danke, aber das hilft nur bedingt. Da ich ja die Fenstergröße dynamisch an den jeweils in der Hilfe-Datei gespeicherten Inhalt anpassen möchte..
Wenn die Seite zu gross ist, musst du trotzdem die Fenstergröße fixieren.
Das, was sich anpasst, ist ja das JScrollPane :wink:
 
Hm.... bei setPage steht im Quellcode sowas mit
Thread pl = new PageLoader(null, null, p, loaded, page);

Aber wenn das fertig ist, wird (wenn ich das beim ersten überfliegen richtig sehe) ein
firePropertyChange("document", old, doc);
ausgeführt, vielleicht kannst du einen PropertyChangeListener dranhängen, der das Anpassen der Größe dann ausführt... Ist aber NUR ein SPONTANER Tipp ohne Gewähr....
 
Hi 😀 ,

vielen Dank, habe es damit geschafft. Das Zauberwort war allerdings nicht firePropertyChange("document"... sondern firePropertyChange("page"...

Den Code 2 habe ich demnach zwischen Zeile 18 und 47 wie folgt ergänzt. Meine letzte Frage hierzu:

?? Geht das Ganze nicht irgendwie eleganter bzw. übersichtlicher und mit weniger "Programmieraufwand" ??

Code:
if (ae.getActionCommand().equals("help")) {
			System.out.println("Die \"Hilfe\" aus dem Datei-Menu wurde aufgerufen.");				
			
			JEditorPane helpText = new JEditorPane();
			helpText.setEditable(false);						
				
			JScrollPane scrollPane = new JScrollPane();
			scrollPane.setViewportView(helpText);
		
			JButton closeButton = new JButton("Hilfe schließen");
			closeButton.addActionListener(new ActionListener() {
				@Override public void actionPerformed(ActionEvent ae) {
					getTopLevelWindow(ae.getSource()).dispose();
				}
			});
			
			JDialog helpDialog = new JDialog((JFrame)getTopLevelWindow(ae.getSource()),"Hilfe",true);
			helpDialog.setResizable(false);								
			helpDialog.setLayout(new BorderLayout());
			helpDialog.add(scrollPane);
			helpDialog.add(closeButton,BorderLayout.SOUTH);
			
			helpText.addPropertyChangeListener(new PropertyChangeListener() {
				@Override public void propertyChange(PropertyChangeEvent pe) {
					if(pe.getPropertyName().equals("page")) {
						JEditorPane pane = (JEditorPane)pe.getSource();
						JDialog dialog = (JDialog)pane.getTopLevelAncestor();
                        dialog.pack();						
                        dialog.setVisible(true);
					}					
				}
			});			
			try {
				helpText.setPage(new File("hilfe.htm").toURI().toURL());
			} catch (IOException e) {
				System.out.println(e.getMessage());
			}					    																
		}
 
Noch eine andere Frage hierzu, weil mir das alles recht kompliziert erscheint:

Was mache ich denn, wenn ich mehrere solche "Probleme" in einem JDialog habe, z.b. Einlesen von 2 HTML-Dateien in zwei getrennte Fenster. Wo setze ich denn dann den dialog.pack(), ohne ihn doppelt programmiert zu haben bzw. dass das Fenster dann versucht wird zweimal angezeigt zu werden? Muss ich dann eine Kommunikation zwischen den einzelnen JEditorPanels aufmachen, die dann checked, ob wirklich ALLE abgearbeitet wurden? Wie realisiere ich dann das? Nicht zu vergessen die Frage von der letzten Nachricht: Geht das Ganze auch einfacher?

Vielen herzlichen Dank für Eure Mühe

BigBaer
😀
 
adde beiden JEditorPanes den PropertyChangeListener und zähle eine Variable hoch. Wenn diese Variable um 2 höher als der Ursprungswert ist, dann weißt du, dass beide soweit sind.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben