FocusListener problem

Hello,

I have a focus listener that detects errors in my user interface. When the user enters a non Integer parsable entry, an exception is thrown and the focus is set back to the entry with the error.

However, it seems as if two focus lost function calls are happening when this occurs. What is causing this. My code is below:

//import the necessary java packages

import java.awt.*;//for the awt widgets

import javax.swing.*;//for the swing widgets

import java.awt.event.*;//for the event handler interfaces

//no import is needed for the DisplayCanvas class

//if in the same directory as the DemoShape class

publicclass DemoShapeextends JApplet

{

//declare private data members of the DemoShape class

//declare the entry and display panel containers

private Container entire;//houses entryPanel and displayCanvas

private JPanel entryPanel;//accepts the user entries into widgets

private DisplayCanvas drawCanvas;//displays the response of entries

//required control buttons for the entryPanel

private JTextField widthShapeText, heightShapeText, messageText, fontSizeText;

private ButtonGroup shapeRadio;

private JRadioButton rect, oval, roundRect;

private JComboBox shapeColorDrop, fontTypeDrop, fontColorDrop;

//arrays of strings to be used later in combo boxes

String displayFonts[] ={"Dialog","Dialog Input","Monospaced",

"Serif","Sans Serif"};

String javaFonts[] ={"Dialog","DialogInput","Monospaced",

"Serif","SansSerif"};

String shapes[] ={"Rectangle","Round Rectangle","Oval"};

String colors[] ={"Black","Blue","Cyan","Dark Gray",

"Gray","Green","Light Gray","Magenta","Orange",

"Pink","Red","White","Yellow"};

Color javaColors[] ={Color.black, Color.blue, Color.cyan, Color.darkGray,

Color.gray, Color.green, Color.lightGray,

Color.magenta, Color.orange, Color.pink, Color.red,

Color.white, Color.yellow};

//declare public data members of the DemoShape class

//init method to initialize the applet objects

publicvoid init()

{

//declare variables to assist with the layout

//these are the left and right justified x coordinates

int ljX = 10;int rjX = 150;

//this is the y coordinates for the rows

int yRow1 = 10;//the shape rows

int yRow2 = 40;

int yRow3 = 60;

int yRow4 = 130;

int yRow5 = 150;

int yRow6 = 210;//the message rows

int yRow7 = 240;

int yRow8 = 260;

int yRow9 = 300;

int yRow10 = 320;

int yRow11 = 360;

int yRow12 = 380;

//these are the widths for the text boxes, drop downs

//message entry, big message entry and radio buttons

int tWidth = 30;int dWidth = 110;

int mWidth = 250;int bmWidth = 250;

int rWidth = 125;

//the height is universal, even for the messages!

int height = 25;

//set a content pane for the entire applet

//set the size of the entire window and show the entire applet

entire = this.getContentPane();

entire.setLayout(new GridLayout(1, 2));

//create the entry panel and add it to the entire pane

entryPanel =new JPanel();

entryPanel.setLayout(null);

entire.add(entryPanel);

//create the display canvas and add it to the entire pane

//this will display the output

drawCanvas =new DisplayCanvas();

drawCanvas.setBackground(Color.white);

entire.add(drawCanvas);

//

//entry panel code

//

//add the form elements in the form of rows

//the first row (label)

JLabel entryLabel =new JLabel("Enter Shape Parameters:");

entryPanel.add(entryLabel);

entryLabel.setBounds(ljX, yRow1, bmWidth, height);

//second row (labels)

JLabel shapeTypeLabel =new JLabel("Select Shape:");

shapeTypeLabel.setBounds(ljX, yRow2, mWidth, height);

entryPanel.add(shapeTypeLabel);

JLabel shapeColorLabel =new JLabel("Select Shape Color:");

shapeColorLabel.setBounds(rjX, yRow2, mWidth, height);

entryPanel.add(shapeColorLabel);

//third row (entry)

rect =new JRadioButton("Rectangle",true);

oval =new JRadioButton("Oval",false);

roundRect =new JRadioButton("Round Rectangle",false);

rect.setBounds(ljX, yRow3, rWidth, height);

oval.setBounds(ljX, yRow3 + 20, rWidth, height);

roundRect.setBounds(ljX, yRow3 + 40, rWidth, height);

rect.addItemListener(new changeListen());

oval.addItemListener(new changeListen());

roundRect.addItemListener(new changeListen());

shapeRadio =new ButtonGroup();

shapeRadio.add(rect);

shapeRadio.add(oval);

shapeRadio.add(roundRect);

entryPanel.add(rect);

entryPanel.add(oval);

entryPanel.add(roundRect);

shapeColorDrop =new JComboBox(colors);

shapeColorDrop.setBounds(rjX, yRow3, dWidth, height);

shapeColorDrop.addItemListener(new changeListen());

entryPanel.add(shapeColorDrop);

//the fourth row (labels)

JLabel widthShapeLabel =new JLabel("Enter Width:");

widthShapeLabel.setBounds(ljX, yRow4, mWidth, height);

entryPanel.add(widthShapeLabel);

JLabel heightShapeLabel =new JLabel("Enter Height:");

heightShapeLabel.setBounds(rjX, yRow4, mWidth, height);

entryPanel.add(heightShapeLabel);

//the fifth row (entry)

widthShapeText =new JTextField("200", 3);

widthShapeText.setBounds(ljX, yRow5, tWidth, height);

widthShapeText.addFocusListener(new focusListen());

entryPanel.add(widthShapeText);

heightShapeText =new JTextField("200", 3);

heightShapeText.setBounds(rjX, yRow5, tWidth, height);

heightShapeText.addFocusListener(new focusListen());

entryPanel.add(heightShapeText);

//the sixth row (label)

JLabel messageLabel =new JLabel("Enter Message Parameters:");

messageLabel.setBounds(ljX, yRow6, bmWidth, height);

entryPanel.add(messageLabel);

//the seventh row (labels)

JLabel messageEntryLabel=new JLabel("Enter Message:");

messageEntryLabel.setBounds(ljX, yRow7, mWidth, height);

entryPanel.add(messageEntryLabel);

//the eighth row (entry)

messageText =new JTextField("Enter your message.");

messageText.setBounds(ljX, yRow8, mWidth, height);

messageText.addFocusListener(new focusListen());

entryPanel.add(messageText);

//the ninth row (label)

JLabel fontTypeLabel =new JLabel("Select Font:");

fontTypeLabel.setBounds(ljX, yRow9, mWidth, height);

entryPanel.add(fontTypeLabel);

JLabel fontColorLabel =new JLabel("Select Font Color:");

fontColorLabel.setBounds(rjX, yRow9, mWidth, height);

entryPanel.add(fontColorLabel);

//the tenth row (entry)

fontTypeDrop =new JComboBox(displayFonts);

fontTypeDrop.setBounds(ljX, yRow10, dWidth, height);

fontTypeDrop.addItemListener(new changeListen());

entryPanel.add(fontTypeDrop);

fontColorDrop =new JComboBox(colors);

fontColorDrop.setBounds(rjX, yRow10, dWidth, height);

fontColorDrop.addItemListener(new changeListen());

entryPanel.add(fontColorDrop);

//the eleventh row (label)

JLabel fontSizeLabel =new JLabel("Select Font Size:");

fontSizeLabel.setBounds(ljX, yRow11, mWidth, height);

entryPanel.add(fontSizeLabel);

//the final row (entry)

fontSizeText =new JTextField("12", 2);

fontSizeText.setBounds(ljX, yRow12, tWidth, height);

fontSizeText.addFocusListener(new focusListen());

entryPanel.add(fontSizeText);

//

//set the applet to visible

//

//set to visible and display

entire.setSize(800, 600);

entire.setVisible(true);

}//end the init method

//paint method

publicvoid paint(Graphics g)

{

//call the demoShape's superclass constructor

super.paint(g);

//repaint the canvas

drawCanvas.repaint();

}//end paint method

//begin the DisplayCanvas

privateclass DisplayCanvasextends Canvas

{

//declare private data members to house the width and height of the canvas

privateint canWidth;

privateint canHeight;

//declare private data members for the shape and message

private String message;

private String shape;

private Color sColor;

privateint sWidth;

privateint sHeight;

private String font;

private Color ftColor;

privateint ftSize;

//declare public data members

//constructor of DisplayCanvas

public DisplayCanvas()

{

//set all data members to defaults

canWidth = 0;

canHeight = 0;

message ="Enter your message.";

shape ="rect";

sColor = Color.black;

sWidth = 200;

sHeight = 200;

font ="Serif";

ftColor = Color.black;

ftSize = 12;

}//end the constructor

//begin the setMessage function

publicvoid setMessage(String m){ message = m;}

//begin the setShape function

publicvoid setShape(String s){ shape = s;}

//begin the setSColor function

publicvoid setSColor(Color sC){ sColor = sC;}

//begin the setSWidth function

publicvoid setSWidth(int w){ sWidth = w;}

//begint the setSHeight

publicvoid setSHeight(int h){ sHeight = h;}

//begin the setFont method

publicvoid setFont(String f){ font = f;}

//begin the setFtColor method

publicvoid setFtColor(Color ftC){ ftColor = ftC;}

//begin the setFtSize

publicvoid setFtSize(int ftS){ ftSize = ftS;}

//begin the public paint function of ShowShape

publicvoid paint(Graphics g)

{

//

//set and output the shape according to the arguments

//

//set the width and height

//this must be done in the paint method (not init())

canWidth = this.getWidth();

canHeight = this.getHeight();

//determine the x and y of the shape

int x = (canWidth - sWidth) / 2;

int y = (canHeight - sHeight) / 2;

//set the color for the graphic object

g.setColor(sColor);

//output the shape

//if the shape is a rectangle

if(shape.equals("rect"))

{ g.drawRect(x, y, sWidth, sHeight);}

//else if it is a oval

elseif(shape.equals("oval"))

{ g.drawOval(x, y, sWidth, sHeight);}

//else it is a round rectangle

else

{ g.drawRoundRect(x, y, sWidth, sHeight, 25, 25);}

//

//set and output the message according to the arguments

//

//set the color and the font for the graphic object

g.setColor(ftColor);

g.setFont(new Font(font, Font.PLAIN, ftSize));

//determine the centering of the message

//get the width and height of the message

FontMetrics metrics = g.getFontMetrics();

int mW = metrics.stringWidth(message);

int mH = metrics.getHeight();

//if the message is too wide for the shape

if(mW > sWidth)

{ JOptionPane.showMessageDialog(null,"Message is too wide for the shape.");}

//else if the message is too tall for the shape

elseif(mH > sHeight)

{ JOptionPane.showMessageDialog(null,"Message is too tall for the shape.");}

//else print the message

else

{ g.drawString(message, (canWidth - mW) / 2, (canHeight - mH) / 2);}

}//end the paint function of ShowShape class

}//end the DisplayCanvas class

//declare an inner class to handle events

privateclass focusListenimplements FocusListener

{

//supply the implementation of the actionPerformed method

//pass an event variable as the argument

publicvoid focusLost(FocusEvent e)

{

//check the entries with possibilities for errors

//if widthShapeText lost focus

if(e.getSource() == widthShapeText)

{

int widthShapeInt = 0;//integer to house wrapper conversion

//test for integer parsing

try

{

//try parsing the int and send the width

widthShapeInt = Integer.parseInt(widthShapeText.getText());

//test the width of the shape within the canvas

if(widthShapeInt > drawCanvas.getWidth()){thrownew Exception();}

//set the canvas parameter

drawCanvas.setSWidth(widthShapeInt);

}

//catch and process the exception

catch(Exception swException)

{

JOptionPane.showMessageDialog(null,"Error, width must be numeric and less than " + drawCanvas.getWidth() +".");

widthShapeText.requestFocus();

}

//check if width it too wide

}//end if focus left widthShapeText

//if heightShapeText lost focus

elseif(e.getSource() == heightShapeText)

{

int heightShapeInt = 0;//integer to house wrapper conversion

//test for integer parsing

try

{

//test entry for integer parsing

heightShapeInt = Integer.parseInt(heightShapeText.getText());

//test the width of the shape within the canvas

if(heightShapeInt > drawCanvas.getHeight()){thrownew Exception();}

//set the canvas parameter

drawCanvas.setSHeight(heightShapeInt);

}

//catch and process the exception

catch(Exception shException)

{

JOptionPane.showMessageDialog(null,"Error, height must be numeric and less than " + drawCanvas.getHeight() +".");

heightShapeText.requestFocus();

}

//check if height it too high

}//end else if heightShapeText lost focus

//if messageText

elseif(e.getSource() == messageText)

{

//send the message to the canvas

drawCanvas.setMessage(messageText.getText());

}//end else if messageText lost focus

//if fontSizeText lost focus

elseif(e.getSource() == fontSizeText)

{

int fontSizeInt = 0;//integer to house wrapper conversion

//test for integer parsing

try

{

//test entry for integer parsing

fontSizeInt = Integer.parseInt(fontSizeText.getText());

//set the canvas parameter

drawCanvas.setFtSize(fontSizeInt);

}

//catch and process the exception

catch(Exception fsException)

{

JOptionPane.showMessageDialog(null,"Error, font size must be numeric.");

fontSizeText.requestFocus();

}

}//end else fontSizeText has focus

//repaint the canvas after any focus lost above

drawCanvas.repaint();

}//end focusLost method

//implement an empty focus gained function

publicvoid focusGained(FocusEvent e){}

}//end testListen class

//declare an inner class to handle events

privateclass changeListenimplements ItemListener

{

//begin the itemStateChanged method

publicvoid itemStateChanged(ItemEvent e)

{

//if shapeColorDrop was changed

if(e.getSource() == shapeColorDrop)

{ drawCanvas.setSColor(javaColors[shapeColorDrop.getSelectedIndex()]);}

//if fontTypeDrop was changed

elseif(e.getSource() == fontTypeDrop)

{ drawCanvas.setFont(javaFonts[fontTypeDrop.getSelectedIndex()]);}

//if fontColorDrop was changed

elseif(e.getSource() == fontColorDrop)

{ drawCanvas.setFtColor(javaColors[fontColorDrop.getSelectedIndex()]);}

//check the radio buttons

//if fontColorDrop was changed

elseif(e.getSource() == rect)

{ drawCanvas.setShape("rect");}

//if fontColorDrop was changed

elseif(e.getSource() == roundRect)

{ drawCanvas.setShape("roundRect");}

//if fontColorDrop was changed

elseif(e.getSource() == oval)

{ drawCanvas.setShape("oval");}

//repaint the canvas after any change above

drawCanvas.repaint();

}//end itemStateChanged method

}//end changeListen class

}//end DemoShape class

[30126 byte] By [VanJay2] at [2007-9-27 21:12:24]
# 1
Just my first impression, but it might be that when one of your components is losing focus another one is gaining focus. Right up to the point where JOptionPane gets focus. Then then other one loses focus and generates an event.
bbritta at 2007-7-7 3:04:25 > top of Java-index,Archived Forums,New To Java Technology Archive...