Swing Rausfahren

Status
Nicht offen für weitere Antworten.

U2nt

Bekanntes Mitglied
Hallo erstmal!

Ich habe ein JFrame, ganz simpel (nur zum Testen), auf dem eine Checkbox liegt. Ich will nun, dass wenn man auf die checkBox klickt (sprich itemStateChanged()) die JFrame größe von 300, 200 auf 600, 200 vergrößert. Das ist natürlich nicht schwer, ich will nun, dass das Fenster sozusagen "rausfährt". Dazu habe ich mir gedacht: Ich prüfe mittels einer while-Schleife, ob die maximal größe (maxdim.width) kleiner oder gleich der aktuellen Größe(getSize().width) ist. Anschließend setzt er die Größe um +1 in x Richtung größer, und schläft anschliessend mit Thread.sleep(1). Hier der Code:
Java:
				public void itemStateChanged(java.awt.event.ItemEvent e) {
					if(startCB.isSelected()) {
						while(getSize().width < maxdim.width) {
							setSize(getSize().width + 1, getSize().height);
							validate();
							try {
								Thread.sleep(1);
							} catch(InterruptedException ex) {
								
							}
						}
					}
				}

Nun ist mein Problem, dass wenn ich auf die Checkbox klicke, das JFrame sich zwar wunderbar vergrößert, aber der Bereich, umden sich das JFrame vergrößert, ist schwarz, bis zur Beendigung der while Schleife, und die checkBox ist auch bis zur Beendigung der while schleife noch nicht "eingehakt", also so, als würde man einfach gedrückthalten.

KURZ: Ich will, dass das JFrame beim rausfahren nicht schwarz wird/ist.

Danke schon jetzt für Antworten :)

(PS: Ich benutzen den Visual Editor für Eclipse :p)
 

javimka

Top Contributor
Das könnte etwa so aussehen:
Java:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JCheckBox;
import javax.swing.JFrame;

public class FlowFrame extends JFrame {

	private Thread flowThread;
	
	public FlowFrame() {
		super("Fliessendes Fenster");
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(new FlowLayout());
		
		for (int i=1;i<10;i++) {
			JCheckBox cbx = new JCheckBox(i*100+"x"+i*100);
			final int s = i;
			cbx.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					flowSize(s*100,s*100);
				}
			});
			add(cbx);
		}
		
		setSize(200,200);
		setLocationRelativeTo(null);
	}
	
	private void flowSize(final int width, final int height) {
		if (flowThread!=null) {
			flowThread.interrupt();
		}
		flowThread = new Thread() {
			public void run() {
				try {
					int steps = 50;
					int oldW = getWidth();
					int oldH = getHeight();
					for (int i=0;i<steps && !isInterrupted() ;i++) {
						setSize(oldW+(width-oldW)/steps*i,
								oldH+(height-oldH)/steps*i);
						Thread.sleep(20);
					}
				} catch (InterruptedException e) {
					// interupted, während sleep
				}
			}
		};
		flowThread.start();
	}
	
	public static void main(String[] args) {
		FlowFrame frame = new FlowFrame();
		frame.setVisible(true);
	}
}
 

Marco13

Top Contributor
... wobei das setSize dann eigentlich wieder mit SwingUtilities auf den EDT gelegt werden sollte...
 

javimka

Top Contributor
Stimmt
Java:
	private void flowSize(final int width, final int height) {
		if (flowThread!=null) {
			flowThread.interrupt();
		}
		flowThread = new Thread() {
			public void run() {
				try {
					final int steps = 50;
					final int oldW = getWidth();
					final int oldH = getHeight();
					for (int i=0;i<steps && !isInterrupted() ;i++) {
						final int ii = i;
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								setSize(oldW+(width-oldW)/steps*ii,
										oldH+(height-oldH)/steps*ii);
							}
						});
						Thread.sleep(20);
					}
				} catch (InterruptedException e) {
					// interupted, während sleep
				}
			}
		};
		flowThread.start();
	}

Ein anderer Ansatz wäre javax.swing.Timer zu verwenden. Nach einer gewissen Zeit, wenn das Frame die Grösser erreicht haben soll, müsste sich der Timer dann selber stoppen.
 

Ebenius

Top Contributor
Tipp: Nicht [c]Thread.run()[/c] überschreiben, sondern [c]Runnable[/c] implementieren und an den [c]Thread[/c] übergeben. Die API-Doc von [c]Runnable[/c] erklärt wieso:
In most cases, the Runnable interface should be used if you are only planning to override the run() method and no other Thread methods. This is important because classes should not be subclassed unless the programmer intends on modifying or enhancing the fundamental behavior of the class.
Ebenius
 

U2nt

Bekanntes Mitglied
Wow, vielen Dank für die schnellen Antworten, jetzt klappts bei mir super :)

Ich machs gleich mal als erledigt :)
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben