I'm trying to make a simple JDialog, which asks the user for input in the form of 3 text fields, and it displays correctly and its PropertyListener works perfectly fine, I haven't assigned a parent for the JDialog in it's constructor, so I'm guessing by default the parent is set to be the ancestor of all the components in my applet. However, when I change from the applet to, say a firefox window and when I click back on my applet, the JDialog has disappeared. Would I need to set a certain property to the JDialog to make sure it stays even when I switch windows. The starnge thing is that I think the dialog is still up, but invisible, because when another dialog appears after the first has disappeared, both dialog appear at once(the first dialog reappearing). MY code for the JDialog is just below:
private void addQuestion() {
questionTextField = new TextField(50);
Object[] componentsArray = {"Question:", questionTextField, "MQLYes:", mqlYesTextField, "MQLNo:", mqlNoTextField};
Object[] options = {"Enter", "Cancel"};
addQuestionDialog = new JDialog(new JFrame(),"Add question");
addQuestionPane = new JOptionPane(componentsArray, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, null, options, options[0]);
int x = getX() + getWidth()/2, y = getY() + getHeight()/2;
addQuestionDialog.setContentPane(addQuestionPane);
addQuestionDialog.setResizable(false);
addQuestionDialog.setSize(300,210);
addQuestionDialog.setVisible(true);
addQuestionDialog.setLocation(x, y);
addQuestionDialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
addQuestionPane.addPropertyChangeListener(this);
}
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (addQuestionDialog.isVisible() && (e.getSource() == addQuestionPane) && (JOptionPane.VALUE_PROPERTY.equals(prop) || JOptionPane.INPUT_VALUE_PROPERTY.equals(prop))) {
Object value = addQuestionPane.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
//ignore reset
return;
}
//Reset the JOptionPane's value.
//If you don't do this, then if the user
//presses the same button next time, no
//property change event will be fired.
addQuestionPane.setValue(
JOptionPane.UNINITIALIZED_VALUE);
if (value.equals("Enter")) {
String questionTypedText = questionTextField.getText();
String mqlYesTypedText = mqlYesTextField.getText();
String mqlNoTypedText = mqlNoTextField.getText();
sqlModel.addQuestion(questionTypedText, mqlYesTypedText, mqlNoTypedText);
questionTextField.setText("");
mqlYesTextField.setText("");
mqlNoTextField.setText("");
} else { //user closed dialog or clicked cancel
addQuestionDialog.setVisible(false);
}
}
}
I've checked the code several time and I don't see any issues with it, and the dialogs do what they're supposed to do, so I'm guessing there's a special addQuestion.set...(Object setValue) method which I should be adding in.
Would I need to set a certain property to the JDialog to make sure it stays even when I switch windows.
Yes.
I haven't assigned a parent for the JDialog in it's constructor,
and that would be the problem. The dialog will be visible whenever the owner of the dialog is visible, so you need to specify the owner JFrame.
Related
I have rename dialog for rename file
String renameTo = JOptionPane.showInputDialog(gui, "New Name", currentFile.getName());
it works this way, but I have a problem.
the problem is that I set the default value with the extension of the file
but I just want the file name to be selected.
sample : my file name = yusuf.png
I want select only yusuf like;
There is a lot going on inside JOptionPane, it's one of the things that makes it so powerful, it also makes it a little inflexible to.
Two immediate problems are apparent...
You can't gain direct access to the JTextField been used to get input from the user
The JOptionPane wants to control which components have focus when the dialog is first shown.
Setting up the JTextField is actually straight forward...
String text = "yusuf.png";
int endIndex = text.lastIndexOf(".");
JTextField field = new JTextField(text, 20);
if (endIndex > 0) {
field.setSelectionStart(0);
field.setSelectionEnd(endIndex);
} else {
field.selectAll();
}
This will basically select all the text from the start of the String up to the last . or all the text if no . can be found.
The difficult part now is taking back focus control from the JOptionPane
// Make a basic JOptionPane instance
JOptionPane pane = new JOptionPane(field,
JOptionPane.PLAIN_MESSAGE,
JOptionPane.OK_CANCEL_OPTION,
null);
// Use it's own dialog creation process, it's simpler this way
JDialog dialog = pane.createDialog("Rename");
// When the window is displayed, we want to "steal"
// focus from what the `JOptionPane` has set
// and apply it to our text field
dialog.addWindowListener(new WindowAdapter() {
#Override
public void windowActivated(WindowEvent e) {
// Set a small "delayed" action
// to occur at some point in the future...
// This way we can circumvent the JOptionPane's
// focus control
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
field.requestFocusInWindow();
}
});
}
});
// Put it on the screen...
dialog.setVisible(true);
dialog.dispose();
// Get the resulting action (what button was activated)
Object value = pane.getValue();
if (value instanceof Integer) {
int result = (int)value;
// OK was actioned, get the new name
if (result == JOptionPane.OK_OPTION) {
String newName = field.getText();
System.out.println("newName = " + newName);
}
}
And, crossing our fingers, we end up with something looking like...
Personally, I'd wrap this up in a nice reusable class/method call which returned the new text or null based on the action of the user, but that's me
Isn't there an easier way?
Of course, I just like showing you the most difficult solution possible ... 😳 (sarcasm) ... it's kind of why I suggested wrapping it up in it's own utility class, so you can re-use it later 😉
Here I want to open a DialogFrame containing an error message when a buttonGroup is not active & the search button is clicked. So inside the ActionEvent I have made the DialogFrame to setVisible(true). But when the button group is active & I click the search button (inside the if condition), the setVisible(false) doesn't seem to work, in other word the DialogFrame still pop ups!
How can I turn the visibility off of the DialogFrame inside the if condition?
private void jButtonSearchActionPerformed(java.awt.event.ActionEvent evt) {
SrchEMsg sem = new SrchEMsg(this);
sem.setVisible(true);
sem.setLocationRelativeTo(null);
sem.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
if (bgGroup.getSelection() != null) {
sem.setVisible(false); //doesn't work.
SrchResult sr = new SrchResult();
sr.setVisible(true);
sr.pack();
sr.setLocationRelativeTo(null);
sr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.dispose();
}
}
I would recommend not to manipulate the visibility but simply not to create sem at all if some condition is met:
if (bgGroup.getSelection() == null) {
// only handle `sem`
SrchEMsg sem = new SrchEMsg(this);
sem.setVisible(true);
sem.setLocationRelativeTo(null);
sem.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
} else {
// only handle `sr`
SrchResult sr = new SrchResult();
sr.setVisible(true);
sr.pack();
sr.setLocationRelativeTo(null);
sr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.dispose();
}
Keep it simple. Get rid of
sem.setVisible(true);
and instead simply do
sem.setVisible(bgGroup.getSelection() == null);
only set it visible if need be
If instead your wish to set the dialog invisible when the user makes a selection, then you can't do this in dialog creation code, but rather need to respond to the appropriate event, such as an ActionListener or ItemListener added to your JRadioButtons.
I have a UI in which I want to display a popup with a slider bar, with a message, and have the user be able to click OK or Cancel after choosing a value (or not). JOptionPane has various show methods that seem like they'd be useful, but I was unable to find much about making them do what I want.
This is actually a question that I had to root around to find an answer to, and I'll provide it below. I hope it will be useful to someone else.
The examples I was able to find had the standard flaw of examples: they weren't close enough to what I wanted to tell me how to do this, and didn't explain enough about how things worked to alter them on my own. I finally ran across a tutorial which explained that the "messages" in the dialog could be components, and the JOptionPane code would render them. This example uses a JSlider, I assume other JComponents could be used as well.
The documentation also talks about what to do if you want to "display the dialog directly", but I never did figure out what they meant by that.
I stumbled around in various forms of JOptionPane methods before figuring out the following:
/**
* display the dialog for entering the number of spots to move the first
* marble chosen after a 7 is played. Returns 0 if the user cancelled this
* operation.
*/
#Override
public int getMoveCount()
{
int moveCount = 0;
JSlider slider = createSlider();
JPanel sliderPanel = createSliderPanel("myMessage", slider);
String title = "myTitle";
int dialogResponse = JOptionPane.showOptionDialog
(this, // I'm within a JFrame here
sliderPanel,
title,
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, null, null
);
if (JOptionPane.OK_OPTION == dialogResponse)
{ moveCount = slider.getValue(); }
else { moveCount = 0; } // works for cancel button, red 'x', and keyboard escape key
return moveCount;
}
private JSlider createSlider()
{
JSlider slider = new JSlider(1,7);
slider.setMajorTickSpacing(1);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setValue(7); // default to 7
return slider;
}
I have a panel just with a Jtextfield that only accept numbers. So, when I press enter will load a user profile. this is just to see his profile.
What I want: When I press ENTER again all the profile will be cleared, and when I press the numbers and press ENTER again and load the profile again and again...
My problem: I pressed enter and the profile is cleared (Ok all fine), but when I enter the number and press the ENTER, The numbers are cleared and nothing happens, it is like a loop in matriculaTxt.addKeyListener(new KeyAdapter() { ... }
Sorry for my bad English.
private void matriculaTxtActionPerformed(java.awt.event.ActionEvent evt)
{
String matricula = matriculaTxt.getText().trim();
if (!matricula.matches("[0-9]+")) {
matriculaTxt.setText("");
} else {
fc = new FrequenciaController();
matriculaTxt.setEditable(false);
matriculaTxt.requestFocus();
fc.checkinManual(Integer.parseInt(matricula));
}
// the problem is here.
matriculaTxt.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
nomeTxt.setText("");
statusTxt.setText("");
imageLb.setIcon(null);
acessoLabel.setText("");
matriculaTxt.setText("");
observacaoTxt.setText("");
System.err.println("ENTER");
PendenciasTableModel ptm = new PendenciasTableModel();// vazio
pendenciasTabela.setModel(ptm);
matriculaTxt.setEditable(true);
matriculaTxt.requestFocus();
}
}
});
}
What I wanted to do was simple. The user types in the text field their numbers, pressing ENTER: their data are loaded. requestFocus() into the text field and it will not be editable anymore, because when I press Enter again the field will be editable but everything will be deleted, and so on.
First off, you should never use a KeyListener for this sort of thing. Consider instead using either a JFormattedTextField or using a DocumentFilter to prevent non-numeric entry. Next, you should use an ActionLIstener to have the JTextField accept and react to the user's pressing the Enter key.
Edit
You state:
my exact requirements is, when i press ENTER again all data will be cleaned for a new data be inserted.
Why not simply have in your JTextField's ActionLIstener:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText();
// do what you want with text here
// clear the text
textComp.setText("");
}
Again, you should not use a KeyListener for any of this stuff.
Edit 2
If you want a multi-state action listener, one that reacts differently depending on the state of the program, then give it some if blocks to allow it to react to the state of the JTextField. If the field is empty, do one thing, if it has numbers, do another, if it has text, show a warning and clear it:
#Override
public void actionPerformed(ActionEvent e) {
// get the text
JTextComponent textComp = (JTextComponent) e.getSource();
String text = textComp.getText().trim(); // trim it to rid it of white space
if (text.isEmpty()) {
// code to show a profile
return; // to exit this method
}
// if we're here, the field is not empty
if (!text.matches("[0-9]+")) {
// show a warning message here
} else {
// numeric only data present
// do action for this state
}
// clear the text
textComp.setText("");
}
The key again is to not use a KeyListener, but rather to "listen" for the enter key press with the ActionListener only, but to react differently depending on the state of the program, here likely being depending on what content is present in the JTextField.
I think that your problem that the KeyListener it'll not trigger, it will not execute the code inside it, because whenever you press ENTER it will trigger the matriculaTxtActionPerformed then declared the KeyLister, so the ENTER will effect it.
before I start, I'm a beginner programmer.
How can I enable a text field when a button is clicked.
I have two frames, one that has the JFields and the other for the exception.
When the exception occurs > setEditable(false)
but what statement should I make to enable the JFields once the user click on okay button -that i've made in the exception-?
I've tried to add static boolean to exception frame, and inside the action performed of this class I initialized that boolean to true.
in the other class, I added an if statment, if that boolean is true, then setEditable(true)
-========-
The point of this program, that when the exception occurs the user cannot enter anything in the fields until he closes the exception window.
I wish you'd help me.
With all love, programmers.
The code of action performed for THE EXCEPTION WINDOW FRAME ( having Okay button. )
public void actionPerformed(ActionEvent e){
{
allow=true; //static boolean
Container TheFrame = OKButton.getParent();
do TheFrame = TheFrame.getParent();
while (!(TheFrame instanceof JFrame));
((JFrame) TheFrame).dispose();
}
The code of action performed for THE MAIN PROGRAM (having three fields, an exception will occur once the user enters non digits )
I added some comments to clarify.
public void actionPerformed(ActionEvent event) {
try{
r =Double.parseDouble(RField.getText());
s=Double.parseDouble(SField.getText());
h=Double.parseDouble(HField.getText());
Cone C = new Cone(r,s,h);//class cone
if (event.getSource() instanceof JButton) {
JButton clickedButton = (JButton) event.getSource();
if (clickedButton == VolumeButton) {
Result.append("VOLUME = "+C.volume()+ "\n");
ifV= true;//this's for clearing the fields for new entries.
}
if (clickedButton == AreaButton) {
Result.append("SURFACE AREA = "+C.surfaceArea()+ "\n");
ifA= true;//this's for clearing the fields for new entries.
}
if(ifA&&ifV){ // clearing the fields for new entries.
SField.setText(CLEAR);
HField.setText(CLEAR);
RField.setText(CLEAR);
ifV=false; ifA= false;}
}
SList.addShape(C);
}
catch(NumberFormatException e){
//Object of type "Exception__" already created
Ex.setVisible(true);//class "Exception__" is the one i've made for Exception window
SField.setText(CLEAR);
HField.setText(CLEAR);
RField.setText(CLEAR);
SField.setEditable(false);
HField.setEditable(false);
RField.setEditable(false);
}/*here, if the user clicked on -that okay in Exception window-
and variable allow initialized to "true" those statements should extend. I guess?
- everything worked correctly except for this ?*/
if(Ex.allow){
SField.setEditable(true);
HField.setEditable(true);
RField.setEditable(true); }
}
THANK YOU ALL IT FINALLY WORKED.
I added
Ex.allow(SField,HField,RField);
to the catch.
and added this method in class Exception__:
public void allow(JTextField js,JTextField jh,JTextField jr){
HField =jh;
SField =js;
RField =jr;
}
finally, to the action performed of class Exception__:
SField.setEditable(true);
HField.setEditable(true);
RField.setEditable(true);
WOHOOOO. It feels so awesome lol. Thanks all. should I delete my question or leave it for others who might face the same problem as mine? :P
Your question needs a lot more detail. But if all you want to to show an 'exception window' and allow the user to do anything else only after she dismisses this window, I think all you need is a MessageDialog:
See JOptionPane
If you need more details to be displayed you can create your own modal JDialog.
See How to Make Dialogs
Make the text field hiden by writing:
jTextfield.setVisible(fasle);
in the constructor of your form code. than use the button event " Action -> Action Performed " and write the code:
jTextfield.setVisible(true);
and thus your text field will be visible only after the button will be clicked.