-
Bug
-
Resolution: Fixed
-
P1
-
1.1
-
1.1.1
-
generic
-
generic
-
Not verified
This is Win32 specific problem.
Vertical position of a LightWeightCompoent is computed
incorrectly when the componet is added to a Frame. Insets (for a title
bar) is disregarded from the comutation. Due to this arithmetic error,
effect of MouseEvent.MOUSE_ENTERED, for example, is positioned slightly
differently than expected (vertically).
A sample program to cause this error is attached below.
import java.awt.*;
import java.awt.event.*;
public class Test extends Frame implements Runnable, ActionListener {
TestContainer southContainer;
TestContainer centerContainer;
TestButton button1;
TestButton button2;
TextArea messageBox;
Thread thread;
int counter;
public Test() {
super();
String[] fontList =
Toolkit.getDefaultToolkit().getFontList();
setFont(new Font(fontList[0], Font.BOLD, 16));
setLayout(new BorderLayout());
button1 = new TestButton("click to continue");
button1.addActionListener(this);
button2 = new TestButton("more information");
button2.addActionListener(this);
messageBox = new TextArea("Message Box", 4, 12,
TextArea.SCROLLBARS_NONE);
centerContainer = new TestContainer();
centerContainer.setLayout(new
FlowLayout(FlowLayout.CENTER, 16,
16));
centerContainer.add(messageBox, BorderLayout.CENTER);
add(centerContainer, BorderLayout.CENTER);
southContainer = new TestContainer();
southContainer.setLayout(new
FlowLayout(FlowLayout.CENTER, 16,
16));
southContainer.add(button1);
southContainer.add(button2);
add(southContainer, BorderLayout.SOUTH);
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
pack();
counter = 0;
thread = new Thread(this);
thread.start();
}
public static void main(String[] arg) {
new Test().setVisible(true);
}
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == e.WINDOW_CLOSING) {
System.exit(0);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1) {
System.exit(0);
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
drawFace(g);
if (button1 != null) {
button1.drawFace();
}
if (button2 != null) {
button2.drawFace();
}
}
public void run() {
while (true) {
try {
thread.sleep(200);
} catch(InterruptedException e) {
thread.stop();
break;
}
counter = (counter + 2) % 20;
repaint();
}
}
protected void drawFace(Graphics g) {
Dimension s = getSize();
for (int i = counter; i < Math.max(s.width, s.height) *
2; i +=
20) {
g.setColor(getBackground());
g.drawLine(i , 0, 0, i );
g.setColor(getForeground());
g.drawLine(i + 2, 0, 0, i + 2);
}
}
}
class TestContainer extends Container {
public TestContainer() {
super();
}
}
class TestButton extends Component {
String text;
boolean state;
ActionListener actionListener;
public TestButton(String text) {
super();
this.text = text;
state = false;
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
protected void processMouseEvent(MouseEvent e) {
switch (e.getID()) {
case e.MOUSE_ENTERED:
state = true;
drawFace();
break;
case e.MOUSE_EXITED:
state = false;
drawFace();
break;
case e.MOUSE_RELEASED:
processEvent(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, text));
break;
}
}
protected void processEvent(AWTEvent e) {
if (e instanceof ActionEvent) {
processActionEvent((ActionEvent)e);
return;
}
super.processEvent(e);
}
protected void processActionEvent(ActionEvent e) {
if (actionListener != null) {
actionListener.actionPerformed(e);
}
}
public void drawFace() {
Graphics g = getGraphics();
if (g != null) {
Dimension size = getSize();
FontMetrics fm = g.getFontMetrics();
int w = fm.stringWidth(text);
if (state) {
g.setColor(Color.red);
}
g.drawString(text, (size.width -
fm.stringWidth(text)) /
2, (size.height - fm.getHeight()) / 2 + fm.getAscent());
g.drawRect(0, 0, size.width - 1, size.height -
1);
g.drawRect(1, 1, size.width - 3, size.height -
3);
g.dispose();
g = null;
}
}
public void addActionListener(ActionListener l) {
actionListener = AWTEventMulticaster.add(actionListener,
l);
}
public void removeActionListener(ActionListener l) {
actionListener =
AWTEventMulticaster.remove(actionListener, l);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
return getMaximumSize();
}
public Dimension getMaximumSize() {
Graphics g = getGraphics();
Dimension size;
if (g != null) {
FontMetrics fm = g.getFontMetrics();
size = new Dimension(fm.stringWidth(text) + 16,
fm.getHeight() + 16);
g.dispose();
g = null;
} else {
size = new Dimension(16, 16);
}
return size;
}
}
Vertical position of a LightWeightCompoent is computed
incorrectly when the componet is added to a Frame. Insets (for a title
bar) is disregarded from the comutation. Due to this arithmetic error,
effect of MouseEvent.MOUSE_ENTERED, for example, is positioned slightly
differently than expected (vertically).
A sample program to cause this error is attached below.
import java.awt.*;
import java.awt.event.*;
public class Test extends Frame implements Runnable, ActionListener {
TestContainer southContainer;
TestContainer centerContainer;
TestButton button1;
TestButton button2;
TextArea messageBox;
Thread thread;
int counter;
public Test() {
super();
String[] fontList =
Toolkit.getDefaultToolkit().getFontList();
setFont(new Font(fontList[0], Font.BOLD, 16));
setLayout(new BorderLayout());
button1 = new TestButton("click to continue");
button1.addActionListener(this);
button2 = new TestButton("more information");
button2.addActionListener(this);
messageBox = new TextArea("Message Box", 4, 12,
TextArea.SCROLLBARS_NONE);
centerContainer = new TestContainer();
centerContainer.setLayout(new
FlowLayout(FlowLayout.CENTER, 16,
16));
centerContainer.add(messageBox, BorderLayout.CENTER);
add(centerContainer, BorderLayout.CENTER);
southContainer = new TestContainer();
southContainer.setLayout(new
FlowLayout(FlowLayout.CENTER, 16,
16));
southContainer.add(button1);
southContainer.add(button2);
add(southContainer, BorderLayout.SOUTH);
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
pack();
counter = 0;
thread = new Thread(this);
thread.start();
}
public static void main(String[] arg) {
new Test().setVisible(true);
}
protected void processWindowEvent(WindowEvent e) {
if (e.getID() == e.WINDOW_CLOSING) {
System.exit(0);
}
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button1) {
System.exit(0);
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
drawFace(g);
if (button1 != null) {
button1.drawFace();
}
if (button2 != null) {
button2.drawFace();
}
}
public void run() {
while (true) {
try {
thread.sleep(200);
} catch(InterruptedException e) {
thread.stop();
break;
}
counter = (counter + 2) % 20;
repaint();
}
}
protected void drawFace(Graphics g) {
Dimension s = getSize();
for (int i = counter; i < Math.max(s.width, s.height) *
2; i +=
20) {
g.setColor(getBackground());
g.drawLine(i , 0, 0, i );
g.setColor(getForeground());
g.drawLine(i + 2, 0, 0, i + 2);
}
}
}
class TestContainer extends Container {
public TestContainer() {
super();
}
}
class TestButton extends Component {
String text;
boolean state;
ActionListener actionListener;
public TestButton(String text) {
super();
this.text = text;
state = false;
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
}
protected void processMouseEvent(MouseEvent e) {
switch (e.getID()) {
case e.MOUSE_ENTERED:
state = true;
drawFace();
break;
case e.MOUSE_EXITED:
state = false;
drawFace();
break;
case e.MOUSE_RELEASED:
processEvent(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, text));
break;
}
}
protected void processEvent(AWTEvent e) {
if (e instanceof ActionEvent) {
processActionEvent((ActionEvent)e);
return;
}
super.processEvent(e);
}
protected void processActionEvent(ActionEvent e) {
if (actionListener != null) {
actionListener.actionPerformed(e);
}
}
public void drawFace() {
Graphics g = getGraphics();
if (g != null) {
Dimension size = getSize();
FontMetrics fm = g.getFontMetrics();
int w = fm.stringWidth(text);
if (state) {
g.setColor(Color.red);
}
g.drawString(text, (size.width -
fm.stringWidth(text)) /
2, (size.height - fm.getHeight()) / 2 + fm.getAscent());
g.drawRect(0, 0, size.width - 1, size.height -
1);
g.drawRect(1, 1, size.width - 3, size.height -
3);
g.dispose();
g = null;
}
}
public void addActionListener(ActionListener l) {
actionListener = AWTEventMulticaster.add(actionListener,
l);
}
public void removeActionListener(ActionListener l) {
actionListener =
AWTEventMulticaster.remove(actionListener, l);
}
public Dimension getMinimumSize() {
return getPreferredSize();
}
public Dimension getPreferredSize() {
return getMaximumSize();
}
public Dimension getMaximumSize() {
Graphics g = getGraphics();
Dimension size;
if (g != null) {
FontMetrics fm = g.getFontMetrics();
size = new Dimension(fm.stringWidth(text) + 16,
fm.getHeight() + 16);
g.dispose();
g = null;
} else {
size = new Dimension(16, 16);
}
return size;
}
}