How show my application delay with JProgressBar? - java

I wrote a simple application and I want show delay of it with JProgressBar Plese help me ;
I want show JProgressBar with Joptionpane , with a cancel button and it should be modal
this is my source code :
class CustomFrame extends JFrame {
private JProgressBar progressBar;
public CustomFrame() {
long start = System.currentTimeMillis();
myMethod();
this.getContentPane().setLayout(null);
this.setSize(200, 200);
//JOptionPane. ?????
this.setTitle("JFrame");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
long end = System.currentTimeMillis();
System.out.print("\nTime: " + (end - start));
}
public void myMethod(){
try {
java.io.File file = new java.io.File("i://m.txt");
BufferedReader input =
new BufferedReader(new FileReader(file));
String line;
while ((line = input.readLine()) != null) {
if (line.indexOf("CREATE KGCGI=") != -1 ){
System.out.println(line);
}
}
input.close();
}
catch(Exception e){
e.printStackTrace();
}
}
Thanks ...

There are a couple things that you will need to do to get this to work:
You should be aware of threading issues in Swing. Your GUI painting should be done on the EventDispatchThread and disk I/O should be done in a worker thread. See this tutorial, the SwingWorker JavaDoc, and SwingUtilities.invokeLater for more detail
You will then want to get the size of your file (file.length())to determine how to scope your progress bar (myProgressBar.setMaximum(length))
When you iterate over the lines in your file, you will want to trigger an update to your progress bar (myProgressBar.setValue(myProgressBar.getValue()+lineLength)).
A couple points by way of critique:
your constructor shouldn't go off and do all of your work (ie load your file and pop up an option pane with the ability to cancel. the constructor should just do the work needed to create the object. you might want to consider having your constructor create your class, and then have the work that needs to be done to be called separately, or within something like an init() method.
It isn't clear what you are doing with the JFrame as superclass. JOptionPane is a class that will pop up a very basic modal dialog with some text, maybe an icon or input field. It isnt a panel that is embedded in a dialog.
As JOptionPane is a very basic construct for creating a basic message dialog, it might be easier to use a JDialog, which can also be made modal. JDialog will allow you to add buttons as you please, where as a standalone JOptionPane will require you to use Yes/No, or Yes/No/Cancel or OK/Cancel etc.
If you still want to use JOptionPane, and only show a cancel button, you can instantiate a JOptionPane (as opposed to using the utility show* methods), with the progressbar as the message, and the JOptionPane.CANCEL_OPTION as the optionType param. You will still need to put this into a JDialog to make it visible. See this tutorial for more details:
JOptionPane (constructor)
Creates a JOptionPane with the specified buttons, icons, message, title, and so on. You must then add the option pane to a JDialog, register a property-change listener on the option pane, and show the dialog. See Stopping Automatic Dialog Closing for details.

Related

Dispose frame In Its Constructor

I want to dispose a frame in its constructor when the condition is true.
this.dispose is not disposing frame. I want that, when my constructor is called, if condition i.e (configurationBean.getCode().equals(macPass)) is true then a new frame have to be called and this frame must have to be closed. Else this frame have to be created.
public ConfigurationFrame() {
String pcMac = getPcMacAddress();
String macPass = getPassword(pcMac);
ConfigurationDao configurationDao = new ConfigurationDaoImpl();
ConfigurationBean configurationBean = configurationDao.checkCode(macPass);
if(configurationBean == null)
initComponents();
else if(configurationBean.getCode().equals(macPass))
{
new MainLoginFrame().setVisible(true);
this.dispose();
super.setVisible(false);
}
}
}
Note that your question is a classic "XY Problem" type question where you ask "how do I do X", when the best solution is "Don't do X but instead do Y". In other words you definitely do not want to dispose of a top-level window object such as a JFrame in its constructor as you're trying to do.
I think that what you want to do (a guess) is to
Test the configuration of things
If OK, display the main GUI
If not OK, then display a window that allows the user to re-set the configuration
Key point: then re-test if the configuration is OK,
And if so, then display main GUI
Repeat as necessary.
If so, then I would use a while loop to show the set configuration window and exit the loop if the configuration is OK, but also allow the user to exit the loop if they simply want to quit or can't set the configuration OK. Something like this:
// configurationGood: true if config is good
// justQuit: true if the user has had enough and wants to quit
while (!configurationGood && !justQuit) {
// create configuration dialog here
// calling constructors, and all
// use a **modal** dialog here
// change configurationGood and/or justQuit values in here
}
if (!justQuit) {
// create and display main application here
}
Note that
this code is not called within any GUI window constructor, but rather prior to displaying the GUI
The re-set configuration window shouldn't be a JFrame but rather a modal JDialog
This way the program code flow halts while the dialog is displayed and only resumes after the dialog has been dealt with.
This allows the code within the while loop to query the dialog the state of its fields and use this to re-test that the configuration is OK

Displaying a JFrame as the result of a JButton click?

I am trying to create a JPanel to display when a user clicks a button within my main JFrame. In Netbeans I first used the wizard to add a new JPanel to my project, I then used the GUI creator to fill in all the content. I am not trying to display the JPanel with the following code
private void m_jbShowSelAccResultsActionPerformed(java.awt.event.ActionEvent evt)
{
Account selAcc = getSelectedAccount();
if(selAcc != null)
{
AccountView accPanel = new AccountView(Account.getDeepCopy(selAcc));
accPanel.setVisible(true);
}
else
ShowMessage("Please select an account to view");
}
But nothing happens, no error is thrown and the JPanel is not shown. So I then changed the JPanel to a JFrame (Netbeans didn't complain). When I try again with the same code I receive the error GroupLayout can only be used with one Container at a time.
How can I display my JPanel/JFrame?
To change views within a Swing GUI, use a CardLayout as this is a much more robust and reliable way to do this.
Don't try to blindly "change a JPanel to a JFrame". It looks like you're just guessing here.
GroupLayout can't be reused as the error message is telling you. Likely this error comes from the point above. If you avoid trying to make a JFrame out of a JPanel, the error message will likely go away. As an aside, GroupLayout is not easily used manually, especially if you're trying to add components to an already rendered GUI.
So for instance, if your program had a JPanel say called cardHolderPanel, that used a CardLayout, this held by a variable say called cardLayout, and you've already added a "card" JPanel to this holder for accounts, say called accPanel, and if the accPanel had a method to set its currently displayed account, say setAccount(Accoint a), you could easily swap views by calling the CardLayout show(...) method, something like:
private void m_jbShowSelAccResultsActionPerformed(java.awt.event.ActionEvent evt) {
Account selAcc = getSelectedAccount();
if(selAcc != null) {
accPanel.setAccount(Account.getDeepCopy(selAcc));
cardLayout.show(cardHolderPanel, "Account View");
}
else {
showErrorMessage("Please select an account to view");
}
}

(Java Swing) Stalling actionPerformed Command Until A Dialog Returns

I need to create a JDialog, or a JFrame class (it doesn't particularly matter so long as it's a graphical interface) - that can be used in a static command that is called from the within the actionPerformed(ActionEvent) handler and will stall that process until the user provides their selections from the user interface.
Obviously it is possible to do, because this is exactly what the dialogs JOptionPane creates does. But when I try to stall the thread until the user has completed the selection process, the interface doesn't display properly.
Here is the part of my code that I'm having trouble with:
public static Results queryForResults(String message, int propertyOne,
int propertyTwo){
MyCustomDialog mcd = new MyCustomDialog(message, propertyOne,propertyTwo);
mcd.show();
// complete() is a boolean property of my MyCustomDialog class that turns
// true when the interface has been completed.
while(!mcd.complete()){
synchronized(mcd){
try{
mcd.wait(10000L);
} catch(InterruptedException e) {
e.printStackTrace();
return null;
}
}
}
mcd.dispose();
// My MyCustomDialog class has a getResults() property which returns
// a Results object (i.e. another custom class I've made to contain
// the selections made by the user.)
return mcd.getResults();
}
The dialog outer frame appears, but it's insides don't. They just seem to be a screen capture of whatever was on the screen beneath the dialog when it appeared. I get the impression that this isn't working because I'm not supposed to be stalling the Swing Event thread with the wait command. So how do you do it?
There is no need for a while loop. A modal JDialog will cause execution to stop in your ActionLIstener until the dialog is closed.
Also, don't use the show() method to display a dialog. You should be using the setVisible(true) method.

How do I change the value of a JOptionPane from a PropertyChangeListener without triggering the listener?

I am trying to make a program to manage a group of sports players. Each player has an enum Sport, and SportManager has convenient factory methods. What I am trying to do is open a dialog that has a JTextField for a name and a combo box to choose a sport. However, I want to stop the user from closing the dialog while the text field is blank, so I wrote a PropertyChangeListener so that when the text field is blank, it would beep to let the user know. However, if the user puts in something in the text after setting off the beep, it doesn't trigger the listener and you can't close the dialog without pressing cancel because the value is already JOptionPane.OK_OPTION, and cancel is the only way to change JOptionPane.VALUE_PROPERTY. So I tried to add
message.setValue(JOptionPane.UNITIALIZED_VALUE);
within the listener. However this just closes the window right away without giving the user a chance to fill in the text field, presumably because it triggers the listener I just registered. How do I make it so that it will beep more than once and give the user a chance to fill in the field?
FYI newPlayer is the component I'm registering the action to.
Code:
newPlayer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Object[] msg = new Object [4];
msg[0] = new JLabel("Name:");
final JTextField nameField = new JTextField();
msg[1]=nameField;
msg[2] = new JLabel("Sport: ");
JComboBox<Sport> major = new JComboBox<Sport>(SportManager.getAllSports());
msg[3]=major;
final JOptionPane message = new JOptionPane();
message.setMessage(msg);
message.setMessageType(JOptionPane.PLAIN_MESSAGE);
message.setOptionType(JOptionPane.OK_CANCEL_OPTION);
final JDialog query = new JDialog(gui,"Create a new player",true);
query.setContentPane(message);
query.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
message.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (query.isVisible()&& (e.getSource() == message)&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
if(nameField.getText().equals("")&&message.getValue().equals(JOptionPane.OK_OPTION)){
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
return;
}
query.dispose();
}
}
});
query.pack();
query.setVisible(true);
if(Integer.parseInt(message.getValue().toString())==JOptionPane.OK_OPTION){
players.add(new Player(nameField.getText(),(Sport)major.getSelectedItem()));
edited=true;
}
gui.show(players);
}
});
I don't think you can do it with JOptionPane but you can using using TaskDialog framework and few others.
You can also create a dialog yourself, attach change listeners to your fields and enable/disable OK button based on content of your fields. This process is usually called "form validation"
However, I want to stop the user from closing the dialog while the
text field is blank
I get where you are going, but Java Swing is not very good at this. There is no way you can prevent the listener from being called. A solution would be to ignore the call, but this is complicated to implement.
The way I solved this issue is to let the pop-up disappear, check the returned value and if it is null/empty, beep and re-open it until user fills something.
JOptionPane does not internally support validation of inputs (Bug Reference). Your best bet is to create your own custom JDialog which supports disabling the OK button when the input data is invalid.
I'd recommend reading the bug report since other people talk about it and give workarounds.
However, I want to stop the user from closing the dialog while the text field is blank
The CustomDialog example from the section in the Swing tutorial on Stopping Automatic Dialog Closing has a working example that does this.
After taking a quick look at your code and the working example I think your code should be something like:
if (query.isVisible()
&& (e.getSource() == message)
&& (prop.equals(JOptionPane.VALUE_PROPERTY)))
{
if (message.getValue() == JOptionPane.UNINITIALIZED_VALUE)
return;
if (nameField.getText().equals("")
&& message.getValue().equals(JOptionPane.OK_OPTION))
{
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
}
else
query.dispose();
}
Otherwise, I'll let you compare your code with the working code to see what the difference is.
One way to solve this problem is to add a Cancel and Ok button to your dialog. Then, disable closing the popup via the X in the corner, forcing the user to click either Cancel or Ok to finish/close the dialog. Now, simply add a listener to the text field that will disable the Ok button if the text field is blank.
Judging from your code I assume you can figure out how to implement these steps, but if you have trouble let us know! Good luck!

JOptionPane won't show its dialog on top of other windows

I have problem currently for my swing reminder application, which able to minimize to tray on close. My problem here is, I need JOptionPane dialog to pop up on time according to what I set, but problem here is, when I minimize it, the dialog will pop up, but not in the top of windows when other application like explorer, firefox is running, anyone know how to pop up the dialog box on top of windows no matter what application is running?
Create an empty respectively dummy JFrame, set it always on top and use it as the component for the JOptionPane instead of null. So the JOptionPane remains always on top over all other windows of an application. You can also determine where the JOptionPane appears on screen with the location of the dummy JFrame.
JFrame frmOpt; //dummy JFrame
private void question() {
if (frmOpt == null) {
frmOpt = new JFrame();
}
frmOpt.setVisible(true);
frmOpt.setLocation(100, 100);
frmOpt.setAlwaysOnTop(true);
String[] options = {"delete", "hide", "break"};
int response = JOptionPane.showOptionDialog(frmOpt, msg, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, "delete");
if (response == JOptionPane.YES_OPTION) {
removeRow();
}
frmOpt.dispose();
}
Old post, but I was struggling with this.
My problem was more with Javafx allowing the JOptionPane to go behind the current Java window.
Therefore I used the following which does what the original poster asked by putting the JOptionPane in front of all windows; even JAVAFX.
Firstly the old JOptionPane:
JOptionPane.showMessageDialog(null, "Here I am");
Now an JOptionPane that stays in front:
final JDialog dialog = new JDialog();
dialog.setAlwaysOnTop(true);
JOptionPane.showMessageDialog(dialog, "Here I am");
And for fun here is everything in one long line:
JOptionPane.showMessageDialog(
((Supplier<JDialog>) () -> {final JDialog dialog = new JDialog(); dialog.setAlwaysOnTop(true); return dialog;}).get()
, "Here I am");
You can make a static method some where that will return the JDialog for you and then just call it in the JOptionPane to clean up your code a bit.
Are you using one of the canned JOptionPanes? (Like JOptionPane.showCOnfirmDialog(...))
You may want to look at extending JDialog and making your own dialog panel, and then calling myDialog.setAlwaysOnTop(true);
Windows is blocking this operation since XP.
The scenario before was like:
Your a tiping in some text in an editor and not recognize that another dialog is coming to front when you are tipping the text. The coming dialog gets the focus and you are tiping in the new dialog. Maybe you click enter after you are ready and do this in the wrong dialog, which is asking whether you realy want to delet your hard disk ;)
The come to front call in java is only working for java windows.
The possibibilty to notify the user of a new window is to implement a Frame, which will highlighted/flashing in the windows task bar.
Correction the post above..
I have resolve my problem as below:
this.setVisible(true); // show main frame
MyDialog dialog = New MyDialog(this, true); // show my custom dialog
dialog.setVisible(true);
this.setVisible(false);
it works fine for me :)
You might think about using a JFrame instead. It may give you a little more flexibility.
If you are using a JFrame and you want it to popup on top of the other windows use:
myFrame.setVisible(true);
myFrame.setState(Frame.NORMAL);
The setState will show the window to the user if it was in minimized state previously.

Categories

Resources