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

