I'm integrating an applet and I need to hack one of the dialog and change its modality.
My problem is I don't know Swing, and my attempts have no effect in practice.
Current implementation:
dialog.setModalExclusionType(ModalExclusionType.TOOLKIT_EXCLUDE);
dialog.repaint();
also tried
dialog.setModal(false);
So there is my question. How can I dynamically change the modality of an existing JDialog ?
don't know what you try to do ...
but maybe you can get something from here
public class Mainz extends JFrame implements ActionListener{
JButton showDialog = new JButton("show dialog");
public Mainz() {
setLayout(new FlowLayout());
showDialog.addActionListener(this);
add(showDialog);
setSize(200, 300);
setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
new Dialogz(this, false);
setEnabled(false);
}
public static void main(String[]args){
new Mainz();
}
}
class Dialogz extends JDialog{
JButton close = new JButton("close");
public Dialogz(JFrame owner,boolean modal) {
super(owner, modal);
setSize(100, 200);
add(close);
setLocationRelativeTo(owner);
setVisible(true);
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
closez();
}
});
}
void closez(){
setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE);
System.out.println("modal exclusion befor = "+getModalExclusionType());
setModalExclusionType(ModalExclusionType.NO_EXCLUDE);
System.out.println("modal exclusion after = "+getModalExclusionType());
System.out.println("modality before ="+getModalityType());
setModal(true);
System.out.println("modality after ="+getModalityType());
getOwner().setEnabled(true);
Dialogz.this.dispose();
}
}
A hack for a hack:
you can change the modality of an existing dialog by calling the private method:
java.awt.Dialog.hideAndDisposePreHandler();
To call this private method - as an example:
private void executeMethod(final Class<?> clazz, final String methodName, final Object instance)
{
final Method method =
Iterables.getOnlyElement(Iterables.filter(
Arrays.asList(clazz.getDeclaredMethods()), new Predicate<Method>()
{
public boolean apply(final Method method)
{
return method.getName().equals(methodName);
}
}));
method.setAccessible(true);
try
{
method.invoke(instance);
}
catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
throw Throwables.propagate(e);
}
}
(This code requires Guava)
And finally call it:
final Dialog myDialog = ...;
executeMethod(Dialog.class, "hideAndDisposePreHandler", myDialog);
To change whether your dialog is modal or modeless, use setModalityType method.
When you call setModal(true), modality type is the same as calling setModalityType(Dialog.DEFAULT_MODALITY_TYPE). The default value is ModalityType.APPLICATION_MODAL.
When you call setModal(false), modality type is set to ModalityType.MODELESS.
The dialog should be not visible when you change its modality. Otherwise, it will not take effect until the dialog is hidden and then shown again.
Moreover the dialog itself has to be programmed to support different modality modes.
When you use a modal dialog, interaction with the owner window (and possibly with other application windows) is blocked. So you show the dialog, dialog.setVisible(true) and this method does not return until the dialog is closed. Then you use the data from the dialog.
A typical modal dialog is Open File: the application can't proceed until it knows which file to load.
In case of modeless dialog, the method dialog.setVisible(true) returns immediately (after showing the dialog on the screen). Pressing buttons in the dialog usually has some effect on other windows and dialogs. And you can interact with other windows of the application while the dialog is shown.
For example, a typical Find dialog selects a search string in the main window. You can return to the main window, and change text, then click Find again and so on.
If you need more help, I can show you a working sample with dialog which works in both modes: modal and modeless.
I guess that you haven't acquired the AWTPermission.toolkitModality permission for your applet.
Another problem could be that the exclusion type isn't supported on your platform -- you can check this with Toolkit.isModalExclusionTypeSupported(java.awt.Dialog.ModalExclusionType).
Related
I have two Jframes where frame1 has some text fields and when a button on frame1 is clicked, I open another JFrame which contains a search box and a JTable containing search results.
When I click on a result row on JTable, I want that particular values to be reflected in the frame1 text fields.
I tried passing the JFrame1's object as a parameter but I have no clear idea on how to achieve this.
Any help would be highly appreciated.
Thanks
First of all, your program design seems a bit off, as if you are using a JFrame for one of your windows where you should in fact be using a JDialog since it sounds as if one window should be dependent upon the other.
But regardless, you pass references of GUI objects the same as you would standard non-GUI Java code. If one window opens the other (the second often being the dialog), then the first window usually already holds a reference to the second window and can call methods off of it. The key often is when to have the first window call the second's methods to get its state. If the second is a modal dialog, then the when is easy -- immediately after the dialog returns which will be in the code immediately after you set the second dialog visible. If it is not a modal dialog, then you probably want to use a listener of some sort to know when to extract the information.
Having said this, the details will all depend on your program structure, and you'll need to tell us more about this if you want more specific help.
For a simple example that has one window open another, allows the user to enter text into the dialog windows JTextField, and then places the text in the first window's JTextField, please have a look at this:
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class WindowCommunication {
private static void createAndShowUI() {
JFrame frame = new JFrame("WindowCommunication");
frame.getContentPane().add(new MyFramePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
// let's be sure to start Swing on the Swing event thread
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MyFramePanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton openDialogeBtn = new JButton("Open Dialog");
// here my main gui has a reference to the JDialog and to the
// MyDialogPanel which is displayed in the JDialog
private MyDialogPanel dialogPanel = new MyDialogPanel();
private JDialog dialog;
public MyFramePanel() {
openDialogeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openTableAction();
}
});
field.setEditable(false);
field.setFocusable(false);
add(field);
add(openDialogeBtn);
}
private void openTableAction() {
// lazy creation of the JDialog
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
dialog = new JDialog(win, "My Dialog",
ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
}
dialog.setVisible(true); // here the modal dialog takes over
// this line starts *after* the modal dialog has been disposed
// **** here's the key where I get the String from JTextField in the GUI held
// by the JDialog and put it into this GUI's JTextField.
field.setText(dialogPanel.getFieldText());
}
}
class MyDialogPanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton okButton = new JButton("OK");
public MyDialogPanel() {
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
okButtonAction();
}
});
add(field);
add(okButton);
}
// to allow outside classes to get the text held by the JTextField
public String getFieldText() {
return field.getText();
}
// This button's action is simply to dispose of the JDialog.
private void okButtonAction() {
// win is here the JDialog that holds this JPanel, but it could be a JFrame or
// any other top-level container that is holding this JPanel
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
win.dispose();
}
}
}
You'd do a very similar technique to get information out of a JTable.
And again, if this information doesn't help you, then please tell us more about your program including showing us some of your code. The best code to show is a small compilable example, an SSCCE similar to what I've posted above.
I have two Jframes where frame1 has some text fields and when a button on frame1 is clicked, I open another JFrame which contains a search box and a JTable containing search results.
When I click on a result row on JTable, I want that particular values to be reflected in the frame1 text fields.
I tried passing the JFrame1's object as a parameter but I have no clear idea on how to achieve this.
Any help would be highly appreciated.
Thanks
First of all, your program design seems a bit off, as if you are using a JFrame for one of your windows where you should in fact be using a JDialog since it sounds as if one window should be dependent upon the other.
But regardless, you pass references of GUI objects the same as you would standard non-GUI Java code. If one window opens the other (the second often being the dialog), then the first window usually already holds a reference to the second window and can call methods off of it. The key often is when to have the first window call the second's methods to get its state. If the second is a modal dialog, then the when is easy -- immediately after the dialog returns which will be in the code immediately after you set the second dialog visible. If it is not a modal dialog, then you probably want to use a listener of some sort to know when to extract the information.
Having said this, the details will all depend on your program structure, and you'll need to tell us more about this if you want more specific help.
For a simple example that has one window open another, allows the user to enter text into the dialog windows JTextField, and then places the text in the first window's JTextField, please have a look at this:
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class WindowCommunication {
private static void createAndShowUI() {
JFrame frame = new JFrame("WindowCommunication");
frame.getContentPane().add(new MyFramePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
// let's be sure to start Swing on the Swing event thread
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
class MyFramePanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton openDialogeBtn = new JButton("Open Dialog");
// here my main gui has a reference to the JDialog and to the
// MyDialogPanel which is displayed in the JDialog
private MyDialogPanel dialogPanel = new MyDialogPanel();
private JDialog dialog;
public MyFramePanel() {
openDialogeBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openTableAction();
}
});
field.setEditable(false);
field.setFocusable(false);
add(field);
add(openDialogeBtn);
}
private void openTableAction() {
// lazy creation of the JDialog
if (dialog == null) {
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
dialog = new JDialog(win, "My Dialog",
ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(dialogPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
}
dialog.setVisible(true); // here the modal dialog takes over
// this line starts *after* the modal dialog has been disposed
// **** here's the key where I get the String from JTextField in the GUI held
// by the JDialog and put it into this GUI's JTextField.
field.setText(dialogPanel.getFieldText());
}
}
class MyDialogPanel extends JPanel {
private JTextField field = new JTextField(10);
private JButton okButton = new JButton("OK");
public MyDialogPanel() {
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
okButtonAction();
}
});
add(field);
add(okButton);
}
// to allow outside classes to get the text held by the JTextField
public String getFieldText() {
return field.getText();
}
// This button's action is simply to dispose of the JDialog.
private void okButtonAction() {
// win is here the JDialog that holds this JPanel, but it could be a JFrame or
// any other top-level container that is holding this JPanel
Window win = SwingUtilities.getWindowAncestor(this);
if (win != null) {
win.dispose();
}
}
}
You'd do a very similar technique to get information out of a JTable.
And again, if this information doesn't help you, then please tell us more about your program including showing us some of your code. The best code to show is a small compilable example, an SSCCE similar to what I've posted above.
I need to perform an action after the JFrame is closed and I have this part of code for it, but this doesn't work.
Could anyone please advise what should be change here?
private void changeDefaults(){
Thread changeDefaultsThread = new Thread(new Runnable(){
public void run(){
Change ch = new Change();
ch.setVisible(true);
ch.setListeners();
ch.defaultInput();
while(ch.isActive()){
System.out.println("active");
}
updateDefaults();
}
});
changeDefaultsThread.start();
}
Change is the JFrame I am opening for another action.
You can add listener to your JFrame
frame.addWindowListener (new java.awt.event.WindowAdapter)
and override the windowClosing
#Override
public void windowClosing
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
//do something
}
});
I'm surprised no one has mentioned the simplest solution: don't use a JFrame. The best tool for this behavior -- displaying a child window and doing something immediately after it has closed -- is to use a modal dialog window such as a JDialog or JOptionPane. The JDialog set up code is very similar to that of the JFrame, with an exception being that it uses different constructors, and should have the parent window passed into it, and it uses a subset of the default close operations.
If you use a modal dialog, then program flow is halted in the calling code immediately after the dialog has been displayed (think of how a JOptionPane operates), and then immediately resumes from the spot after calling setVisible(true) on the dialog once the dialog has been closed.
The only bugaboo is that if you don't want modal behavior -- if you don't want the parent/calling window to be disabled while the child window is displayed -- then you'll have to use a non-modal JDialog window with a WindowListener.
If you want to perform an action when closing a JFrame, you just need to attach a WindowListener (extending WindowAdapter so that you do not need to implement all WindowListener methods):
import javax.swing.*;
public class AfterJFrameClose {
public static void main(String[] args) {
JFrame frame = new JFrame("My frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
frame.addWindowListener(new java.awt.event.WindowAdapter() {
#Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
System.out.println("Frame closing");
}
});
}
}
Instead of the System.out.println, just write the code you want to have executed.
Update: If you want to access another frame, you either should pass it as a parameter as suggested above or you can also iterate through active frames using something like this:
Frame[] frames = Frame.getFrames();
for (Frame frame: frames) {
System.out.println(frame.getTitle());
}
I have a JDialog in my java code, I want to get the indication when the user closes the JDialog, Is there any way in java to get indication when user closes the JDialog???
Simply add a WindowListener to it and override the windowClosing() or windowClosed() methods.
WindowListener.windowClosing() is called when the user attempts to close the window, WindowListener.windowClosed() is called when the window has been closed.
Example:
dialog.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.out.println("User attempted to close the dialog!");
}
});
For a modal dialog, then the code after the call that shows the dialog will not continue until the dialog is closed. I.e.,
JDialog dialog = new JDialog((Frame)null, true); // true = modal
System.out.println("before");
dialog.setVisible();
System.out.println("after"); // <-- won't happen until the dialog is closed
For a non-modal dialog, call dialog.addWindowListener as you would with any other window, with a WindowListener (or WindowAdapter) and override either windowClosing or windowClosed, depending on whether you need to prevent closure or merely detect it.
For best control this I suggest to You to create your own class of dialog that extends Jdialog and then to overwrite the functions setVisible(boolen value) and dispose() . By default when user click close button dialog goes to funciton setVisible(false) but you can change this using setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE). Here is a simple code.
public class MyDialog extends JDialog {
public MyDialog(){
super();
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setSize(new Dimension(200,200));
setVisible(true);
}
public void dispose(){
System.out.println("dialog disposed");
// put your code here
super.dispose();
}
public void setVisible(boolean value) {
System.out.println("dialog set visible : " + value);
// or put your code here
super.setVisible(value);
}
}
Is there a way to disable all X on dialog boxes?
I can accomplish this on one by doing:
JOptionPane pane = new JOptionPane("Are you hungry?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
JDialog dialog = pane.createDialog("Title");
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
} });
dialog.setContentPane(pane);
dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
dialog.pack();
But the problem is thst I have to apply this to other 20-40 dialog boxes which will be time consuming..
So I was wondering just how you can do one line of code to make the fonts bigger on all the Dialog boxes (shown below), is there a way to for the X disable feature.
UIManager.put("OptionPane.messageFont",
new FontUIResource(new
Font("ARIAL",Font.BOLD,30)));
JDialog method setDefaultCloseOperation works just like JFrame's:
http://download.oracle.com/javase/6/docs/api/javax/swing/JDialog.html#setDefaultCloseOperation(int)
Neither will do this for all frames, it will just do it for the instance it is set on. If you want to apply to all your dialogs you need to do one of the following:
Call this every time you construct a dialog.
Extend JDialog and have it set the default for you, then use that new class.
Create a factory method that will construct a dialog with this default set. Then call this method whenever you need a new dialog.
You need to add a windowListener but also set the default close operation for the dialog.
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
this.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
if (someConditionIsMet) {
dispose();
}
}
});
Rather than disable a control, you should remove it. Users shouldn't see an "X" button and then have it not behave like they expect.
See:
Dialog.setUndecorated() for a single dialog
JDialog.setDefaultLookAndFeelDecorated() to provide a hint for future dialogs
Why not just create a custom class that extends the JDialog setting your desired close behavior in the constructor?
class NoCLoseDialog extends JDialog {
NoCloseDialog(){
addWindowListener(new WindowAdaptor(){
// ... Close behavior ...
});
}
}
Crtl+F Replace JDialog with NoCloseDialog ...