Grösse des Frames stimmt nicht von Anfang an

Andi_CH

Top Contributor
Das da unten ist ein Testprogramm und mit diversen Altlasten und unschänem Code versehen ;-) (Also schont eure Tastaturen, wenns nur darum geht 😀 )

Das Programm startet und das Frame hat die Grösse welche zum ersten Tab passt ud nicht die Grösse des grössten Tabs. Wenn man nun das Frame nur ein wenig in der Grösse ändert - erhält es sofort die korrekte Grösse über den SizeChangeHandler.

Der Thread "Resizer" ist einer meiner Versuche, aber da wird hartnäckig die falsche Grösse gesetzt, bis man diese einmal verändert hat - danach bemerkt es auch der Tread.

Jegliche Versuche, dass das Ding von Anfang an die richtige Grösse hat, sind gescheitert. Weiss jemand weiter?

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public final class Example9 implements ActionListener {

	//Constants
	private static final String ACTION_OK             = "OK";
	private static final String ACTION_CANCEL         = "CANCEL";

	private static boolean debug = false;

	private SizeChangeHandler mSizeChangeHandler;

	public void setSizeChangeHandler(SizeChangeHandler sch) {
		mSizeChangeHandler = sch;
	}

	@SuppressWarnings("serial")
	private JComponent buildButtonPanel() {
		JButton mButtonOK     = new JButton();
		JButton mButtonCancel = new JButton();

		Dimension buttonDim = new Dimension(100, 27);

		mButtonOK.setPreferredSize(buttonDim);
		mButtonOK.setActionCommand(ACTION_OK);
		mButtonOK.addActionListener(this);
		mButtonOK.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ACTION_OK);
		mButtonOK.setText("OK");
		mButtonOK.getActionMap().put(ACTION_OK,
				new AbstractAction(ACTION_OK) {
			public void actionPerformed(ActionEvent evt) {
				buttonOK_actionPerformed(evt);
			}
		}
		);
		mButtonCancel.setPreferredSize(buttonDim);
		mButtonCancel.setActionCommand(ACTION_CANCEL);
		mButtonCancel.addActionListener(this);
		mButtonCancel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), ACTION_CANCEL);
		mButtonCancel.setText("Cancel");
		mButtonCancel.getActionMap().put(ACTION_CANCEL,
				new AbstractAction(ACTION_CANCEL) {
			public void actionPerformed(ActionEvent evt) {
				buttonCancel_actionPerformed(evt);
			}
		}
		);
		FormLayout layout = new FormLayout("10dlu, 15dlu, pref, 20dlu, pref, 15dlu, 10dlu");
		DefaultFormBuilder builder = new DefaultFormBuilder(layout, new FormDebugPanel());
		builder.append("", mButtonOK, mButtonCancel, new JLabel(""));
		return builder.getPanel();
	}

	public JComponent buildPanel() {
		// final String format = "fill:175dlu";
		// JTabbedPane tabbedPane = new JTabbedPane();
		JComponent pane = new JTabbedPane();
		pane.putClientProperty("jgoodies.noContentBorder", Boolean.TRUE);

		String example1Text = 
			"Das ist ein kleiner Text. Eine Zeile";

		pane.add("1",
				buildTab("Kurzer Text",
						createArea(example1Text, true, 0, null)));

		String example2Text = 
			"Das ist eine mittellanger Text, der zwei Zeilen belegt. "
			+ "Der Text ist noch zu kurz . ";

		pane.add("2",
				buildTab("Mittlerer Text",
						createArea(example2Text, true, 0, null)));

		String example3Text = 
			"Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. ";

		pane.add("3",
				buildTab("Langer Text",
						createArea(example3Text, true, 0, null)));
		return pane;
	}

	private JTextArea createArea(
			String text,
			boolean lineWrap, 
			int columns,
			Dimension minimumSize) {
		JTextArea area  = new JTextArea(text);
		area.setBorder(new CompoundBorder(
				new LineBorder(Color.GRAY),
				new EmptyBorder(1, 3, 1, 1)));
		area.setLineWrap(lineWrap);
		area.setWrapStyleWord(true);
		area.setColumns(columns);
		area.addInputMethodListener(new TextAreaInputMethodListener());
		area.addComponentListener(new TextAreaCompListener());
		area.addKeyListener(new TextAreaKeyListener());
		if (minimumSize != null) {
			area.setMinimumSize(new Dimension(100, 32));
		}
		return area;
	}

	private JComponent buildTab(String title, /*String columnSpec,*/ JTextArea area) {
		final String columnSpec = "fill:175dlu";
		JLabel columnSpecLabel = new JLabel(columnSpec);
		columnSpecLabel.setHorizontalAlignment(JLabel.CENTER);

		FormLayout layout = new FormLayout(
				columnSpec,
		"pref, 9dlu, pref, 3dlu, fill:default, 9dlu, pref, 9dlu, pref");
		PanelBuilder builder = new PanelBuilder(layout);
		builder.setDefaultDialogBorder();
		CellConstraints cc = new CellConstraints();
		builder.addTitle(title,			cc.xy(1, 1));
		builder.add(columnSpecLabel,	cc.xy(1, 3));
		builder.add(area,				cc.xy(1, 5));
		JComponent buttonPanel = buildButtonPanel();
		builder.add(buttonPanel,	cc.xy(1, 9));
		return builder.getPanel();
	}

	private static class TextAreaKeyListener implements KeyListener {
		private final boolean debug = false;
		final String className = this.getClass().getName() + ".";
		@Override
		public void keyTyped(KeyEvent e) {
			if (debug)
				System.out.println(className + "keyTyped" + e);
		}
		@Override
		public void keyPressed(KeyEvent e) {
			if (debug)
				System.out.println(className + "keyPressed" + e);
		}
		@Override
		public void keyReleased(KeyEvent e) {
			if (debug)
				System.out.println(className + "keyReleased" + e);
		}
	}
	private class TextAreaCompListener implements ComponentListener {
		@Override
		public void componentResized(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentResized - call sizeChangeHandler");
			mSizeChangeHandler.componentResized(null);
		}
		@Override
		public void componentMoved(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentMoved");
		}
		@Override
		public void componentShown(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentShown");
		}
		@Override
		public void componentHidden(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentHidden");
		}
	}
	private static class TextAreaInputMethodListener implements InputMethodListener {
		@Override
		public void inputMethodTextChanged(InputMethodEvent event) {
			System.out.println("TextAreaInputMethodListener.inputMethodTextChanged");
		}
		@Override
		public void caretPositionChanged(InputMethodEvent event) {
			System.out.println("TextAreaInputMethodListener.inputMethodTextChanged");
		}
	}

	// Listens to area size changes and writes the formatted sizes to the given labels.
	private static class SizeChangeHandler extends ComponentAdapter {

		private final JTextArea area;
		private final JFrame	frame;

		private final JLabel    sizeLabel;
		private final JLabel    minSizeLabel;
		private final JLabel    prefSizeLabel;

		private SizeChangeHandler(
				JTextArea area,
				JLabel sizeLabel,
				JLabel minSizeLabel,
				JLabel prefSizeLabel) {
			this.area = area;
			this.sizeLabel = sizeLabel;
			this.minSizeLabel = minSizeLabel;
			this.prefSizeLabel = prefSizeLabel;
			this.frame = null;
		}

		private SizeChangeHandler(JFrame frame) {
			this.area = null;
			this.sizeLabel = null;
			this.minSizeLabel = null;
			this.prefSizeLabel = null;
			this.frame = frame;
		}

		public void componentResized(ComponentEvent evt) {
			if (frame==null) {
				String size = format(area.getSize());
				sizeLabel.setText(size);
				String minSize = format(area.getMinimumSize());
				minSizeLabel.setText(minSize);
				String prefSize = format(area.getPreferredSize());
				prefSizeLabel.setText(prefSize);
			} else {
				Dimension minSize = new Dimension(frame.getMinimumSize());
				if (debug) {
					System.out.println("==========================================================");
					System.out.println("Vorher");
					System.out.println("frame.size = " + format(frame.getSize()));
					System.out.println("frame.minimumSize = " + format(frame.getMinimumSize()));
					System.out.println("frame.preferredSize = " + format(frame.getPreferredSize()));
				}
				System.out.println("Setze size " + minSize);
				frame.setSize(minSize);

				if (debug) {
					System.out.println("----------------------------------------------------------");
					System.out.println("Nachher");
					System.out.println("frame.size = " + format(frame.getSize()));
					System.out.println("frame.minimumSize = " + format(frame.getMinimumSize()));
					System.out.println("frame.preferredSize = " + format(frame.getPreferredSize()));
				}
			}
		}

		private String format(Dimension d) {
			return String.valueOf(d.width) + ", " + d.height;
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("Example9.actionPerformed : " + e);
		this.mSizeChangeHandler.componentResized(null);
		}

	//--------------------------------------------------------------------------------------
	/**
	 * The user pushed the 'Next' button so two positions get created, one for
	 * zone a and one for zone b.
	 * @param the action event
	 */
	private void buttonOK_actionPerformed(ActionEvent e) {
		System.out.println("Example9.buttonOK_actionPerformed()");
	}

	//--------------------------------------------------------------------------------------
	/**
	 * Cancels the mail dialog without sending
	 * @param the action event
	 */
	private void buttonCancel_actionPerformed(ActionEvent e) {
		System.out.println("Example9.buttonCancel_actionPerformed()");
	}

	private static class Resizer extends Thread {
		private final long time;
		private final SizeChangeHandler mSizeChangeHandler;

		public Resizer(long millis, SizeChangeHandler handler) {
			time = millis;
			mSizeChangeHandler = handler;
		}

		@Override
		public void run() {
			try {
				for (int i=1; i<=10; i++) {
					sleep(time);
					System.out.println("Thread: call resized " + i);
					mSizeChangeHandler.componentResized(null);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			} finally {
				System.out.println("Thread: is terminating");
			}
		}
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setTitle("Example9");
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		Example9 ex = new Example9();
		JComponent panel = ex.buildPanel();
		frame.getContentPane().add(panel);
		SizeChangeHandler sch = new SizeChangeHandler(frame);
		ex.setSizeChangeHandler(sch);
		frame.addComponentListener(sch);
		frame.pack();
		frame.setVisible(true);
		final long time = 1000;
		System.out.println("new Thread");
		Thread thr = new Resizer(time, ex.mSizeChangeHandler);
		System.out.println("Thread.start");
		thr.start();
		System.out.println("Thread.started");
	}
}
 
Abgesehen von dem Tipp, das ganze mal mit den SwingUtilties.invokeLater auf dem EDT erstellen zu lassen, nur den allgemeinen Tipp, mit dem man (wenn man genug Zeit hat) selbst aus dem häßlichsten Altlasten-Code noch ein schönes Programm zaubern kann: Tipp 😀
 
Na klar kenne ich die Del Taste - vor allem im Zusammenhang mit Ctrl-Alt (oder halt Strg-Alt) aus früheren Zeiten 😀

sieh mal da 🙂

invokeLater will ein Runnable - äh - was soll ich denn da "invoken?


Das unnötigste mal rausgeschmissen ...

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.builder.PanelBuilder;
import com.jgoodies.forms.debug.FormDebugPanel;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public final class Example10 implements ActionListener {

	//Constants
	private static final String ACTION_OK             = "OK";
	private static final String ACTION_CANCEL         = "CANCEL";

	private SizeChangeHandler mSizeChangeHandler;

	public void setSizeChangeHandler(SizeChangeHandler sch) {
		mSizeChangeHandler = sch;
	}

	@SuppressWarnings("serial")
	private JComponent buildButtonPanel() {
		JButton mButtonOK     = new JButton();
		JButton mButtonCancel = new JButton();

		Dimension buttonDim = new Dimension(100, 27);

		mButtonOK.setPreferredSize(buttonDim);
		mButtonOK.setActionCommand(ACTION_OK);
		mButtonOK.addActionListener(this);
		mButtonOK.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), ACTION_OK);
		mButtonOK.setText("OK");
		mButtonOK.getActionMap().put(ACTION_OK,
				new AbstractAction(ACTION_OK) {
			public void actionPerformed(ActionEvent evt) {
				buttonOK_actionPerformed(evt);
			}
		}
		);
		mButtonCancel.setPreferredSize(buttonDim);
		mButtonCancel.setActionCommand(ACTION_CANCEL);
		mButtonCancel.addActionListener(this);
		mButtonCancel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), ACTION_CANCEL);
		mButtonCancel.setText("Cancel");
		mButtonCancel.getActionMap().put(ACTION_CANCEL,
				new AbstractAction(ACTION_CANCEL) {
			public void actionPerformed(ActionEvent evt) {
				buttonCancel_actionPerformed(evt);
			}
		}
		);
		FormLayout layout = new FormLayout("10dlu, 15dlu, pref, 20dlu, pref, 15dlu, 10dlu");
		DefaultFormBuilder builder = new DefaultFormBuilder(layout, new FormDebugPanel());
		builder.append("", mButtonOK, mButtonCancel, new JLabel(""));
		return builder.getPanel();
	}

	public JComponent buildPanel() {
		JComponent pane = new JTabbedPane();
		pane.putClientProperty("jgoodies.noContentBorder", Boolean.TRUE);

		String example1Text = 
			"Das ist ein kleiner Text. Eine Zeile";

		pane.add("1",
				buildTab("Kurzer Text",
						createArea(example1Text, true, 0, null)));

		String example2Text = 
			"Das ist eine mittellanger Text, der zwei Zeilen belegt. "
			+ "Der Text ist noch zu kurz . ";

		pane.add("2",
				buildTab("Mittlerer Text",
						createArea(example2Text, true, 0, null)));

		String example3Text = 
			"Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. "
			+ "Das ist ein langer Text, der mehrere Zeilen belegt. ";

		pane.add("3",
				buildTab("Langer Text",
						createArea(example3Text, true, 0, null)));
		return pane;
	}

	private JTextArea createArea(
			String text,
			boolean lineWrap, 
			int columns,
			Dimension minimumSize) {
		JTextArea area  = new JTextArea(text);
		area.setBorder(new CompoundBorder(
				new LineBorder(Color.GRAY),
				new EmptyBorder(1, 3, 1, 1)));
		area.setLineWrap(lineWrap);
		area.setWrapStyleWord(true);
		area.setColumns(columns);
		area.addComponentListener(new TextAreaCompListener());
		return area;
	}

	private JComponent buildTab(String title, /*String columnSpec,*/ JTextArea area) {
		final String columnSpec = "fill:175dlu";
		JLabel columnSpecLabel = new JLabel(columnSpec);
		columnSpecLabel.setHorizontalAlignment(JLabel.CENTER);

		FormLayout layout = new FormLayout(
				columnSpec,
		"pref, 9dlu, pref, 3dlu, fill:default, 9dlu, pref, 9dlu, pref");
		PanelBuilder builder = new PanelBuilder(layout);
		builder.setDefaultDialogBorder();
		CellConstraints cc = new CellConstraints();
		builder.addTitle(title,			cc.xy(1, 1));
		builder.add(columnSpecLabel,	cc.xy(1, 3));
		builder.add(area,				cc.xy(1, 5));
		JComponent buttonPanel = buildButtonPanel();
		builder.add(buttonPanel,	cc.xy(1, 9));
		return builder.getPanel();
	}

	private class TextAreaCompListener implements ComponentListener {
		@Override
		public void componentResized(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentResized - call sizeChangeHandler");
			mSizeChangeHandler.componentResized(null);
		}
		@Override
		public void componentMoved(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentMoved");
		}
		@Override
		public void componentShown(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentShown");
		}
		@Override
		public void componentHidden(ComponentEvent e) {
			System.out.println("TextAreaCompListener.componentHidden");
		}
	}

	// Listens to area size changes and writes the formatted sizes to the given labels.
	private static class SizeChangeHandler extends ComponentAdapter {

		private final JTextArea area;
		private final JFrame	frame;

		private final JLabel    sizeLabel;
		private final JLabel    minSizeLabel;
		private final JLabel    prefSizeLabel;

		private SizeChangeHandler(
				JTextArea area,
				JLabel sizeLabel,
				JLabel minSizeLabel,
				JLabel prefSizeLabel) {
			this.area = area;
			this.sizeLabel = sizeLabel;
			this.minSizeLabel = minSizeLabel;
			this.prefSizeLabel = prefSizeLabel;
			this.frame = null;
		}

		private SizeChangeHandler(JFrame frame) {
			this.area = null;
			this.sizeLabel = null;
			this.minSizeLabel = null;
			this.prefSizeLabel = null;
			this.frame = frame;
		}

		public void componentResized(ComponentEvent evt) {
			if (frame==null) {
				String size = format(area.getSize());
				sizeLabel.setText(size);
				String minSize = format(area.getMinimumSize());
				minSizeLabel.setText(minSize);
				String prefSize = format(area.getPreferredSize());
				prefSizeLabel.setText(prefSize);
			} else {
				Dimension minSize = new Dimension(frame.getMinimumSize());
				frame.setSize(minSize);
			}
		}

		private String format(Dimension d) {
			return String.valueOf(d.width) + ", " + d.height;
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("Example10.actionPerformed : " + e);
		this.mSizeChangeHandler.componentResized(null);
	}

	//--------------------------------------------------------------------------------------
	/**
	 * @param the action event
	 */
	private void buttonOK_actionPerformed(ActionEvent e) {
		System.out.println("Example10.buttonOK_actionPerformed()");
	}

	//--------------------------------------------------------------------------------------
	/**
	 * @param the action event
	 */
	private void buttonCancel_actionPerformed(ActionEvent e) {
		System.out.println("Example10.buttonCancel_actionPerformed()");
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setTitle("Example10");
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		Example10 ex = new Example10();
		JComponent panel = ex.buildPanel();
		frame.getContentPane().add(panel);
		SizeChangeHandler sch = new SizeChangeHandler(frame);
		ex.setSizeChangeHandler(sch);
		frame.addComponentListener(sch);
		frame.pack();
		frame.setVisible(true);
	}
}
 
Java:
public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				JFrame frame = new JFrame();
		        frame.setTitle("Example10");
		        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		        Example10 ex = new Example10();
		        JComponent panel = ex.buildPanel();
		        frame.getContentPane().add(panel);
		        SizeChangeHandler sch = new SizeChangeHandler(frame);
		        ex.setSizeChangeHandler(sch);
		        frame.addComponentListener(sch);
		        frame.pack();
		        frame.setVisible(true)
			}
		});
	} //End main

Das meint Marco. Dadurch wird das Frame und das drumrum direkt vom EDT erstellt.
 
War aber nur ein Gedanke, ungetestet. Wenn man das NICHT macht, kann es aber immer wieder mal zu unerklärlichem Verhalten kommen.... Wenns nicht hilft, kann man ja nochmal genauer schauen.
 
Das invokeLater tut - also liegt es nur an meiner Testumgebung - wie das im "scharfen" Programm gemacht wird - na ja - keine Ahnung 😳 (Da ist dieser Dialog nur ein Teilchen)

Schon wieder was gelernt - Danke.

@bERt0r: Nein, habe ich nicht - hm - ich müsste über die Tabs loopen und suchen welches der grösste ist - das habe ich aber gar nicht versucht, weil ja, nach dem Start und "Kick" alles in Ordnung war.
 

Zurück
Oben