Add dialog box when the program is clossed - java

I want to add an option when somebody closes the frame to check if are there any thread running and if there are any I want to display a dialog box which should ask the user if he really wants to exit. The problem is that no matter which is the option of the user the program closes anyway.
Here is what I tried:
private void addActionWhenFrameIsClosed( )
{
addWindowListener( new WindowAdapter( )
{
public void windowClosing( WindowEvent e )
{
if( isThereAnyThreadRunning( ) )
{
int dialogButton = JOptionPane.YES_NO_OPTION;
int dialogResult = JOptionPane.showConfirmDialog( null, "There are some threads running... "
+ "\nAre you sure you want to exit?",
"Warning", dialogButton );
if( dialogResult == JOptionPane.YES_OPTION)
{
dispose( );
}
}
}
} );
}

Please try adding this line of code as first line in addActionWhenFrameIsClosed
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

Related

JOptionPane cancel button and getting input

I'm trying to get the user to input there name if it is left blank it will ask again, if they fill it out it sets a JLabel or hit cancel to get out.
My last if statement is wrong it does not like nameEnt.
public Player() {
//setBackground(Color.green);
setSize(600, 400);
name = new JLabel();//Input hint
JOptionPane nameOption = new JOptionPane();
String nameEnt = nameOption.showInputDialog("First Name: ");
if (!nameEnt.matches("[a-zA-Z]+")) {
name.setText(nameEnt);
}
if (nameEnt.length() == 0) {
//if this condition is true JOption stays until name is entered or canceled
}
if (nameEnt == nameOption.CANCEL_OPTION) {
System.exit(0);
}
}
The JOptionPane.CANCEL_OPTION is a static int field, and you can't compare String with int with ==.
Good practice
In your case you want to use ok and cancel button JOptionPane.showConfirmDialog and JOptionPane.showInputDialog() in one shot and this is not possible, i suggest to use this instead :
JTextField nameF = new JTextField(20);//create TextField
JPanel myPanel = new JPanel();//cerate JPanel
myPanel.add(new JLabel("Name"));
myPanel.add(nameF);//add your JTextField to your panel
int result;
do {
result = JOptionPane.showConfirmDialog(null, myPanel,
"Title of Panel", JOptionPane.OK_CANCEL_OPTION);//add your panel to JOptionPane
if (result == JOptionPane.OK_OPTION) {//if the user press OK then
if (nameF.getText().isEmpty()) {//check if the input is empty
//if this condition is true JOption stays until name is entered or canceled
} else if (!nameF.getText().matches("[a-zA-Z]+")) {//check if the input match with your regex
//name match exactly
//name.setText(nameF.getText());
}
}
} while (result != JOptionPane.CANCEL_OPTION);//If the user hit cancel then exit
As per the JOptionPane API, if the user cancels the dialog, null is returned.
And so the correct solution is to to not to use equals, but rather to check the return value for null and to do this first, before checking its length.
public Player() {
//setBackground(Color.green);
setSize(600, 400);
name = new JLabel();//Input hint
JOptionPane nameOption = new JOptionPane();
String nameEnt = nameOption.showInputDialog("First Name: ");
if (nameEnt == null) {
// user canceled. get out of here.
System.exit(0);
// or return;
// or throw some exception
}
if (!nameEnt.matches("[a-zA-Z]+")) {
name.setText(nameEnt);
}
if (nameEnt.length() == 0) {
//if this condition is true JOption stays until name is entered or canceled
}
// if (nameEnt == nameOption.CANCEL_OPTION) {
// System.exit(0);
// }
}
But why are you creating a JOptionPane this way? Better to use the static method of creation.
// don't use null as the first parameter if the GUI is already showing
String nameEnt = JOptionPane.showInputDialog(null, "First Name: ");
if (nameEnt == null) {
// user canceled. get out of here.
System.exit(0);
}
Or maybe something like this, if you're trying to loop to get input:
public Player() {
setSize(600, 400); // This is not good to do. Ask for details and I'll tell.
name = new JLabel();// Don't forget to add this to the GUI!
String nameEnt = "";
while (nameEnt.trim().isEmpty()) {
// if the GUI is already showing, pass a component from it as the first param here, not null
nameEnt = JOptionPane.showInputDialog(null, "First Name: ");
if (nameEnt == null) {
// user canceled. get out of here.
System.exit(0);
// or return;
// or throw some exception
} else if (!nameEnt.matches("[a-zA-Z]+")) {
name.setText(nameEnt);
} else {
// set it to "" so that we keep looping
nameEnt = "";
}
}
}

Why JOptionPane cannot stop flow of execution, in my application?

String nmEmp = fName.getText();
if(nmEmp.trim().isEmpty() || nmEmp.trim().equals("")){
JOptionPane.showMessageDialog(null, "Empty Name", "Name Confirmation", JOptionPane.YES_OPTION);
}
Why JOptionPane cannot stop flow of execution, in my application ? And java keep running to executing code below JOptionPane, if JOptionPane execution in true condition. And what reason, this happen?. Please help, Thank you
From Java documentation JOptionPane : https://docs.oracle.com/javase/7/docs/api/javax/swing/JOptionPane.html
Direct Use:
To create and use an JOptionPane directly, the standard pattern is
roughly as follows:
JOptionPane pane = new JOptionPane(arguments);
pane.set.Xxxx(...); // Configure
JDialog dialog = pane.createDialog(parentComponent, title);
dialog.show();
Object selectedValue = pane.getValue();
if(selectedValue == null)
return CLOSED_OPTION;
//If there is not an array of option buttons:
if(options == null) {
if(selectedValue instanceof Integer)
return ((Integer)selectedValue).intValue();
return CLOSED_OPTION;
}
//If there is an array of option buttons:
for(int counter = 0, maxCounter = options.length;
counter < maxCounter; counter++) {
if(options[counter].equals(selectedValue))
return counter;
}
return CLOSED_OPTION;

Troubleshooting a delay in my function

I have a delay happening where my pushGreentText does not show up in my EditText until after the last brace of firstrollSP leaves scope. pushGreenText is a custom function on the UI thread I wrote that adds a text to my EditText in XML that overlays a SurfaceView. I would like to see the green text show up right away instead of waiting for the entire moveWholeAITurn sequence. Is there a way to accomplish that? I tried threading firstrollSP but there is still a delay and I thought about maybe threading pushGreenText but I'm not sure that is the answer yet.
Thank you...
static synchronized public void firstRollSP( ) throws InterruptedException
{
//Roll for Player and announce
mGame.mDice.setDie1( mGame.mDiceFirstRoll.getDie1( ) );
mGame.mDice.setRolled( true );
MainActivity.activity.pushTextGreen( Strings.get_First_roll_X_Die1( ) );
//Roll for two and announce
Thread one = new Thread( )
{
public void run( )
{
try
{
Thread.sleep( 2000 );
mGame.mDice.setDie2( mGame.mDiceFirstRoll.getDie2( ) );
while( mGame.mDice.getDie1( ) == mGame.mDice.getDie2( ) )
mGame.mDice.setDie2( (mRng.nextInt( 6 ) + 1) );
}
catch( InterruptedException e )
{
Log.d( "ACtionUP", "Interupted e" );
}
}
};
one.start( );
one.join( );
MainActivity.activity.pushTextGreen( "Android first roll is " + Integer.toString( mGame.mDice.getDie2() ) );
if( H.initWonFirstRoll( ) )
{
MainActivity.activity.pushTextGreen("Player won first roll.");
Thread tInitWon = new Thread( )
{
public void run( )
{
try
{
Thread.sleep( 2000 );
mGame.isFirstRoll = false;
mGame.isTurn = true;
mGameAI.isFirstRoll = false;
mGameAI.isTurn = false;
mGame.mDice.sort( );
mGame.mDice.setRolled( true );
mGame.mDice.setDiceAnimationComplete( true );
mGame.mOppDice.init( );
mGame.mPossibleIndexes.calcPossibleTriangles( );
}
catch( Exception e )
{
Log.d( "ACtionUP", "Interupted e" );
}
}
};
tInitWon.start( );
tInitWon.join( );
}
else
{
MainActivity.activity.pushTextGreen("Android won first roll.");
Thread tDroidWon = new Thread( )
{
public void run( )
{
try
{
Thread.sleep( 2000 );
mGame.isFirstRoll = false;
mGame.isTurn = false;
mGameAI.isFirstRoll = false;
mGameAI.isTurn = true;
mGameAI.mDice.init( );
mGame.mOppDice.init( );
mGame.mDice.sort( );
mGameAI.mDice.setDie1( mGame.mDice.getDie1() );
mGameAI.mDice.setDie2( mGame.mDice.getDie2() );
mGame.mOppDice.setDie1( mGame.mDice.getDie1() );
mGame.mOppDice.setDie2( mGame.mDice.getDie2() );
Thread.sleep( 2000 );
mGameAI.mPossibleIndexes.calcPossibleTrianglesAI( );
}
catch( InterruptedException e )
{
Log.d( "ACtionUP", "Interupted e" );
}
}
};
tDroidWon.start( );
tDroidWon.join( );
if( mGameAI.mPossibleIndexes.anyPossibles( ) )
{
moveWholeTurnAI( );
}
else
{
H.endTurnAI( );
}
}
}
Because the UI thread is an event loop. It will not update the screen until it returns to the main looper and handles the draw event- until whatever function of yours it calls exits.
You should never call thread.join on the main thread. Your app will freeze if you do, it may crash if it trips a watchdog timer. You need to refactor it to not require joins on the UI thread.
In addition, I see a lot of MainActivity.activity. That's a huge code smell- if you're holding the activity in a static variable you will have memory leaks and you are almost certain to have problems if your app is relaunched. Its something you should never do.

SWT Application: Are Draggable Tabs Possible?

I am building a Java application using SWT. One of the requirements of the application is that it have multiple windows. Rather than having "forever independent" windows, I thought it would be cool to implement a feature like in most browsers where you have a single, tabular window, where each tab can be dragged out to create a separate window. After a little research using the Google, it seems possible to accomplish this using JavaFX, but is it possible (and relatively easy) to achieve the same functionality in SWT? Thanks in advance.
While my take might be a little late, here it is nonetheless. Below snippet is a rough POC that allows to drag an item from the CTabFolder and when the item is dropped outside of the bounds of the folder, a shell is opened to show items' content.
public static void main( String[] args ) {
Display display = new Display();
final Shell shell = new Shell( display );
shell.setLayout( new FillLayout() );
final CTabFolder folder = new CTabFolder( shell, SWT.BORDER );
for( int i = 0; i < 4; i++ ) {
CTabItem item = new CTabItem( folder, SWT.CLOSE );
item.setText( "Item " + i );
Text text = new Text( folder, SWT.MULTI );
text.setText( "Content for Item " + i );
item.setControl( text );
}
Listener dragListener = new Listener() {
private CTabItem dragItem;
public void handleEvent( Event event ) {
Point mouseLocation = new Point( event.x, event.y );
switch( event.type ) {
case SWT.DragDetect: {
CTabItem item = folder.getItem( mouseLocation );
if( dragItem == null && item != null ) {
dragItem = item;
folder.setCapture( true );
}
break;
}
case SWT.MouseUp: {
if( dragItem != null && !folder.getBounds().contains( mouseLocation ) ) {
popOut( dragItem, folder.toDisplay( mouseLocation ) );
dragItem.dispose();
dragItem = null;
}
break;
}
}
}
};
folder.addListener( SWT.DragDetect, dragListener );
folder.addListener( SWT.MouseUp, dragListener );
shell.pack();
shell.open();
while( !shell.isDisposed() ) {
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
private static void popOut( CTabItem tabItem, Point location ) {
Control control = tabItem.getControl();
tabItem.setControl( null );
Shell itemShell = new Shell( tabItem.getParent().getShell(), SWT.DIALOG_TRIM | SWT.RESIZE );
itemShell.setLayout( new FillLayout() );
control.setParent( itemShell );
control.setVisible( true ); // control is hidden by tabItem.setControl( null ), make visible again
itemShell.pack();
itemShell.setLocation( location );
itemShell.open();
}
While this example uses a CTabFolder it should also be possible to use the (native) TabFolder instead.
What is certainly missing is visual feedback while dragging an item and a means to abort a drag operation (e.g. Esc key), and probably some more things...

Throw new exception

I have a problem in my code regarding throw new exception.
In one of the JTextField I enter number 0 but it is incorrect and after I click "ENTER" botton in this moment there is thrown new exception message:
throw new Exception("Wrong number of express lanes range beginnig!! \n Please enter positive number!");
The box message appear with error message I can only click "OK". After I click "Ok" I want that the program stop because I want to correct wrong data in the JTextField. I can't do that because after I click "OK the program continues process. How can I stop the program and correct the data?
Here is important part of the code where I see I have a problem.
public class UILayer
{
private JTextField text1, text2, text3, text4, text5, text6;
private void validateNumbers() throws Exception
{
if(!text1.getText().equals("") &&
Integer.parseInt(text1.getText()) <= 0 )
throw new Exception("Wrong number of lanes!! \n Please enter positive number!");
if(!text2.getText().equals("") &&
Integer.parseInt(text2.getText()) <= 0 )
throw new Exception("Wrong number of express lanes!! \n Please enter positive number!");
if(!text3.getText().equals("") &&
Integer.parseInt(text3.getText()) <= 0 )
throw new Exception("Wrong number of express lanes range beginnig!! \n Please enter positive number!");
if(!text4.getText().equals("") &&
Integer.parseInt(text4.getText()) <= 0 )
throw new Exception("Wrong number of express lanes range ending!! \n Please enter positive number!");
if(!text5.getText().equals("") &&
Integer.parseInt(text5.getText()) <= 0 )
throw new Exception("Wrong number of customers!! \n Please enter positive number!");
if(!text6.getText().equals("") &&
Integer.parseInt(text6.getText()) <= 0 )
throw new Exception("Wrong number of max items!! \n Please enter positive number!");
}
protected class EnterClickListener implements ActionListener
{
private SimulationConfig info;
EnterClickListener( )
{
info = new SimulationConfig();
}
#Override
public void actionPerformed( ActionEvent event )
{
try
{
if(!(event.getActionCommand().equals(null )))
{
validateForm();
validateNumbers();
}
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog( null, "Error.\nPlease enter number.",
"Message", JOptionPane.INFORMATION_MESSAGE );
}
catch (Exception e)
{
JOptionPane.showMessageDialog( null, "Error.\n" + e.getMessage() ,
"Message", JOptionPane.INFORMATION_MESSAGE );
}
info.setCustomerRestriction(Integer.parseInt(text5.getText()), Integer.parseInt(text6.getText()));
info.setExpressRange(Integer.parseInt(text3.getText()), Integer.parseInt(text4.getText()));
info.setLanesNum(Integer.parseInt(text1.getText()), Integer.parseInt(text2.getText()));
showProgressBar();
task = blayer.startSimulation(info);
task.addPropertyChangeListener(new PropertyChangeListener());
task.execute();
}
}
put your code
info.setCustomerRestriction(Integer.parseInt(text5.getText())....
......
task.execute();
inside try, after if. like this:
#Override
public void actionPerformed( ActionEvent event )
{
try
{
if(!(event.getActionCommand().equals(null )))
{
validateForm();
validateNumbers();
info.setCustomerRestriction(Integer.parseInt(text5.getText()), Integer.parseInt(text6.getText()));
info.setExpressRange(Integer.parseInt(text3.getText()), Integer.parseInt(text4.getText()));
info.setLanesNum(Integer.parseInt(text1.getText()), Integer.parseInt(text2.getText()));
showProgressBar();
task = blayer.startSimulation(info);
task.addPropertyChangeListener(new PropertyChangeListener());
task.execute();
}
}
catch(NumberFormatException e)
{
JOptionPane.showMessageDialog( null, "Error.\nPlease enter number.",
"Message", JOptionPane.INFORMATION_MESSAGE );
}
catch (Exception e)
{
JOptionPane.showMessageDialog( null, "Error.\n" + e.getMessage() ,
"Message", JOptionPane.INFORMATION_MESSAGE );
}
}
Solution provided by PC is quite better an alternate is just write a user defined Exception class that has the ability to abort the further program execution, as you can reuse it and thus no need of writing same code again(In case if you are going to handle the same Exception in multiple places or java classes).
What you need to do is:
Take a public class extending to RuntimeException, Exception or
Throwable according to your requirement
Take a public constructor with a String parameter
Call to super(your_String_parameter_here); form inside of your
constructor(So that if you are skipping to handle this Exception and
direct handle to Super class Exception the appropriate message can
be passed up to there)
override toString() method to provide proper string message for your
Exception class object
Now you can reuse this Exception class any where in your code.

Categories

Resources