Schönen guten Tag allerseits.Ich hab hier schon wieder ein paar relativ billige Fragen.
1. Frage:
Ich habe mich nie so genau damit beschäftigt, aber irgendwie dachte ich immer, dass bei Swing alle gefeuerten events auf den event dispatch thread kommen. Zumindest hat sich für mich das hier:
Dies ist anscheinend doch nicht der Fall, hab mir hier diesen code aus javax.swing.AbstractButton angeschaut:
[highlight=Java]
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = getActionCommand();
}
e = new ActionEvent(AbstractButton.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
[/highlight]
Da werden anscheinend einfach alle(???:L) Listener durchlaufen, und bei den wird direkt actionPerformed() aufgerufen. Das ist so üblich und gut so, es gibt keinen Grund hier irgendwelche Konstrukte mit invokeLater() in irgendwelche queues zu schieben, richtig? Okay, gut, umso besser.
2. Frage: (eher nur aus Neugier) Versteht einer was diese Rückwärtssaltos in 2er schritten sollen? War eine foreach-schleife (oder halt eine normale schleife die von 0 bis "n" läuft...) zu langeweilig oder wie? ???:L
3. Frage:
Angenommen ich habe mir ein spezielles JComponent geschrieben, das eine private variable enthält, die bei jeder Größenänderung neuberechnet werden muss. Ich habe versucht, es einfach dadurch zu lösen, dass ich an dieses JComponent einen ComponentListener anhänge und auf Größenänderungen höre.
Kleines (wenn ihr wollt sogar kompilierbares^^) Beispiel:
[highlight=Java]
import javax.swing.*;
import java.awt.event.*;
public class ResizeReaction {
private static class A extends JComponent implements ComponentListener{
private int value;
public A(){
value=0;
addComponentListener(this);
}
private void updateValue(){
value=this.getWidth()*this.getHeight();
}
public int getValue(){
return value;
}
@Override public void componentHidden(ComponentEvent arg0) {}
@Override public void componentMoved(ComponentEvent arg0) {}
@Override public void componentShown(ComponentEvent arg0) {}
@Override
public void componentResized(ComponentEvent arg0) {
updateValue();
}
}
public static void main(String..._){
JFrame f=new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(100,100);
f.setLayout(null);
A a=new A();
f.getContentPane().add(a);
a.setSize(1,1); //<--- das schafft der awt thread meistens, value wird auf 1 gesetzt
f.setVisible(true);
a.setSize(1,2); //<--- das schafft der awt thread nicht so schnell, value wird erst später 2
//wie warte ich hier korrekt auf die ausfuehrung von componentResized()?
/* einfach brutal eine sekunde warten geht natürlich, ist aber hässlich
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
System.out.println(a.getValue());//hier würde ich gerne 2 rauskriegen, irgendwie...
}
}
[/highlight]
Könntet ihr mir bitte mal einen Tipp geben, wie ich auf die neuberechnung des "value" korrekt warte? Komme irgendwie nicht drauf... :autsch:
Vielen Dank im Voraus.
1. Frage:
Ich habe mich nie so genau damit beschäftigt, aber irgendwie dachte ich immer, dass bei Swing alle gefeuerten events auf den event dispatch thread kommen. Zumindest hat sich für mich das hier:
(aus Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 16.5 Es tut sich was – Ereignisse beim AWT ) genau so angehört, dass alle gefeuerten Events einfach in einer langen Liste landen, und alle nacheinander abgearbeitet werden.Die Reihenfolge, in der die Listener abgearbeitet werden, ist im Prinzip undefiniert. Zwar reiht sie Sun in ihrer Implementierung in eine Liste ein, sodass es dadurch eine Reihenfolge gibt, doch sollte es keine Beachtung dieses Implementierungsdetails geben.
Dies ist anscheinend doch nicht der Fall, hab mir hier diesen code aus javax.swing.AbstractButton angeschaut:
[highlight=Java]
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners==ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
if(actionCommand == null) {
actionCommand = getActionCommand();
}
e = new ActionEvent(AbstractButton.this,
ActionEvent.ACTION_PERFORMED,
actionCommand,
event.getWhen(),
event.getModifiers());
}
((ActionListener)listeners[i+1]).actionPerformed(e);
}
}
}
[/highlight]
Da werden anscheinend einfach alle(???:L) Listener durchlaufen, und bei den wird direkt actionPerformed() aufgerufen. Das ist so üblich und gut so, es gibt keinen Grund hier irgendwelche Konstrukte mit invokeLater() in irgendwelche queues zu schieben, richtig? Okay, gut, umso besser.
2. Frage: (eher nur aus Neugier) Versteht einer was diese Rückwärtssaltos in 2er schritten sollen? War eine foreach-schleife (oder halt eine normale schleife die von 0 bis "n" läuft...) zu langeweilig oder wie? ???:L
3. Frage:
Angenommen ich habe mir ein spezielles JComponent geschrieben, das eine private variable enthält, die bei jeder Größenänderung neuberechnet werden muss. Ich habe versucht, es einfach dadurch zu lösen, dass ich an dieses JComponent einen ComponentListener anhänge und auf Größenänderungen höre.
Kleines (wenn ihr wollt sogar kompilierbares^^) Beispiel:
[highlight=Java]
import javax.swing.*;
import java.awt.event.*;
public class ResizeReaction {
private static class A extends JComponent implements ComponentListener{
private int value;
public A(){
value=0;
addComponentListener(this);
}
private void updateValue(){
value=this.getWidth()*this.getHeight();
}
public int getValue(){
return value;
}
@Override public void componentHidden(ComponentEvent arg0) {}
@Override public void componentMoved(ComponentEvent arg0) {}
@Override public void componentShown(ComponentEvent arg0) {}
@Override
public void componentResized(ComponentEvent arg0) {
updateValue();
}
}
public static void main(String..._){
JFrame f=new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(100,100);
f.setLayout(null);
A a=new A();
f.getContentPane().add(a);
a.setSize(1,1); //<--- das schafft der awt thread meistens, value wird auf 1 gesetzt
f.setVisible(true);
a.setSize(1,2); //<--- das schafft der awt thread nicht so schnell, value wird erst später 2
//wie warte ich hier korrekt auf die ausfuehrung von componentResized()?
/* einfach brutal eine sekunde warten geht natürlich, ist aber hässlich
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
*/
System.out.println(a.getValue());//hier würde ich gerne 2 rauskriegen, irgendwie...
}
}
[/highlight]
Könntet ihr mir bitte mal einen Tipp geben, wie ich auf die neuberechnung des "value" korrekt warte? Komme irgendwie nicht drauf... :autsch:
Vielen Dank im Voraus.