My problem is this. I got this two windows that work together and move together.
However if I then open broweser or something that will go in front of the screen, and then I try to show my program in front by clicking it on taskbar, then only one window goes in front. Dialog is in the back and I dont know how to fixe it.
I know there is function ToFront() however I stil dont know how to use it in this scenario.
Instead of creating two JFrames, create a JFrame for your main window and create all other windows as non-modal JDialogs, with the JFrame as their owner. This will cause them to be stacked as a single group; whenever the user brings one to the front, all are brought to the front.
This should solve your problem, as VGR already said... Non-modal Dialog will follow it's parent:
public class FocusMain extends JFrame {
private static FocusMain frame;
private static JDialog dialog;
private JCheckBox checkBox;
private JPanel contentPane;
public static void main(String[] args) {
frame = new FocusMain();
frame.setVisible(true);
dialog = new JDialog(frame);
dialog.setSize(100, 100);
}
public FocusMain() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
setContentPane(contentPane);
checkBox = new JCheckBox("show dialog");
checkBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (checkBox.isSelected()) {
dialog.setVisible(true);
} else {
dialog.setVisible(false);
}
}
});
contentPane.add(checkBox);
}
}
With extended JDialog you will need to pass the parent frame through the constructor and if your constructor looks like this: public ExtendedJDialog(JFrame parentFrame) then you can connect it with it's parent frame with super(parentFrame); as the first line in your constructor...
public class FocusMain extends JFrame {
private static FocusMain frame;
private static FocusDialog dialog;
private JCheckBox checkBox;
private JPanel contentPane;
public static void main(String[] args) {
frame = new FocusMain();
frame.setVisible(true);
dialog = new FocusDialog(frame);
}
public FocusMain() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
setContentPane(contentPane);
checkBox = new JCheckBox("show dialog");
checkBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (checkBox.isSelected()) {
dialog.setVisible(true);
} else {
dialog.setVisible(false);
}
}
});
contentPane.add(checkBox);
}
}
and extended JDialog
public class FocusDialog extends JDialog {
public FocusDialog(JFrame parentFrame) {
super(parentFrame);
setSize(100, 100);
}
}
if you need the dialog to block the parent, use super(parentFrame, true);
Related
I had a frame with two buttons. The first button opened a second frame and the other button was closing it. It worked. Now I want to make a single button that opens a frame and by clicking it again the frame shall close. But it is not working. I set boolean conditions. By clicking the button once it is set from false to true. If it is set to "true" the actionListener is supposed to recognize that annother action (close frame) shall be performed. But nothing happens. Here the code.
public class Main {
public static void main(String[] args) {
FrameOne frameOne = new FrameOne ();
}
}
.
public class FrameOne extends JFrame implements ActionListener {
private FrameTwo frameTwo;
private boolean frameIsOpen = false; // By clicking the button once the value is set to true.
private JButton btn = new JButton();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
FrameOne(){
btn.addActionListener(this);
add(btn);
setSize(400,400);
setLocation(300, 250);
setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public void actionPerformed(ActionEvent e) {
if(e.getSource() == btn && frameIsOpen == false) {
frameTwo = new FrameTwo(); // Opens the new frame
boolean frameIsOpen = true;} // Fulfills the condition for the else if statement.
else if (e.getSource() == btn && frameIsOpen == true) {
frameTwo.dispatchEvent(new WindowEvent(frameTwo, WindowEvent.WINDOW_CLOSING)); }
}
}
.
public class FrameTwo extends JDialog {
FrameTwo() {
setSize(400,400);
setLocation(900, 250);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
}
You do not need having a boolean value. You can make the frameTwo null when you close it. Then check if it is null and create/show a new dialog. Also since you want to create a new dialog every time (and not hide it), I suggest you instead of frameTwo.dispatchEvent(new WindowEvent(frameTwo, WindowEvent.WINDOW_CLOSING)); to use frameTwo.dispose().
An example:
public class TestFrame extends JFrame {
private JDialog dialog;
public TestFrame() {
super("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JButton button = new JButton("open");
button.addActionListener(e -> {
if (dialog == null) {
dialog = new CustomDialog();
dialog.setVisible(true);
} else {
dialog.dispose();
dialog = null;
}
});
add(button);
setLocationByPlatform(true);
pack();
}
static class CustomDialog extends JDialog {
public CustomDialog() {
super();
add(new JLabel("hello world"));
setLocationByPlatform(true);
pack();
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new TestFrame().setVisible(true));
}
}
I have created three classes:
public class Gui extends JFrame {
private final JButton buttonClose = new JButton("Close");
private final MyButtonListener buttonListener = new MyButtonListener(this);
private final MyWindowListener windowListener = new MyWindowListener();
public SwitchGuiExtListeners() {
super("Switch");
setSize(200, 150);
setLayout(new BorderLayout());
add(buttonClose, BorderLayout.EAST);
buttonClose.addActionListener(this.buttonListener);
this.addWindowListener(this.windowListener);
setVisible(true);
}
public JButton getButtonClose() {
return buttonClose;
}
}
public class SwitchGuiWindowListener implements WindowListener{
...
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
...
}
public class MyButtonListener implements ActionListener {
private final Gui gui;
public MyButtonListener (final Gui gui) {
this.gui = gui;
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == gui.getButtonClose()){
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//System.exit(0);
}
}
}
If I use the gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); my frame doesn't close. But when I use the System.exit(0) it works. Why can't I use the setDefaultCloseOperation(..)?
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); does not close a JFrame. It simply tells that the JFrame must exit when the close button on top-right corner of a window is clicked i.e., just sets the behavior but does trigger an exit.
To close a JFrame, use something like this:
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
Source: https://stackoverflow.com/a/1235994/1866196
I have the following problem:
I have a main application window (JFrame) that fills the whole screen.
When a button is clicked, a smaller window appears, to let the user input some Data. While the User does this, the main window should neither jump in front of it, nor allow interaction.
Solution to that: open a modal JDialog. Lets call that Dialog 1.
But when a button within this Dialog is clicked, a NEW window (yes/no-dialog) is supposed to pop up.. and, again, needs to act modal on the already modal JDialog Dialog 1. Trying to do that, the second Dialog keeps disappearing behind the first one.
I tried making Dialog 1 a JFrame but then, of course, I loose the "modal" bit. Forcing Dialog 1 to stay in from still keeps the main window's Button clickable.
What am I missing? How can I put a modal swing window OVER another modal swing window?
Edit:
minimal example of one not-really working version:
Main class for opening:
public class MainWin extends JFrame {
public MainWin(){
this.setSize(800,800);
JButton b = new JButton("click hehe");
this.getContentPane().add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Dia1(MainWin.this);
}
});
this.setVisible(true);
}
}
Main window:
public class MainWin extends JFrame {
public MainWin(){
this.setSize(800,800);
JButton b = new JButton("click hehe");
this.getContentPane().add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Dia1(MainWin.this);
}
});
this.setVisible(true);
}
}
First Dialog:
public class Dia1 extends JDialog {
public Dia1(final JFrame parent){
super(parent, true);
this.setSize(400, 400);
JButton b = new JButton("click hehe");
this.getContentPane().add(b);
this.setVisible(true);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
new Dia2(parent);
}
});
}
}
Second Dialog:
public class Dia2 extends JDialog {
public Dia2(JFrame parent){
super(parent, true);
this.setSize(200, 200);
JButton b = new JButton("click hehe");
this.getContentPane().add(b);
this.setVisible(true);
}
}
PS: I just realised: Dialog 2 is not hidden, as I suspected.. it is simply not there. Most likely because the parent window is blocked from the Modal Dialog?
Here is an MCVE of modality working as advertised.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class ModalOverModal {
private JComponent ui = null;
ModalOverModal() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new GridLayout());
ui.setBorder(new EmptyBorder(40,40,40,40));
final JButton b1 = new JButton("Open Modal Dialog");
b1.setMargin(new Insets(40, 200, 40, 200));
ui.add(b1);
final JButton b2 = new JButton("Open 2nd Modal Dialog");
ActionListener al1 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(b1, b2);
}
};
b1.addActionListener(al1);
ActionListener al2 = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(b2, "Close Me!");
}
};
b2.addActionListener(al2);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
ModalOverModal o = new ModalOverModal();
JFrame f = new JFrame("Modal over Modal");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
I'm trying to add a JPanel to my JFrame within an actionListener method, but it appears only after the second click on the button. This is a portion of my code where panCours is a JPanel and ConstituerData the targeted JFrame :
addCours.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
panCours.setBounds(215, 2, 480, 400);
panCours.setBorder(BorderFactory.createTitledBorder("Saisir les données concernant le cours"));
ConstituerData.this.getContentPane().add(panCours);
}
});
I don't understand why it doesn't appear as soon as I click on the button. Any explanation and help about how to fix this ?
You'll need to add a call to repaint(); (as well as probably revalidate();) to get the JPanel to show immediately. A basic example demonstrating your problem (and the solution) below;
public class Test {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
JButton button = new JButton("Test");
button.setBounds(20, 30, 100, 40);
button.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
JPanel panel = new JPanel();
panel.setBackground(Color.red);
panel.setBounds(215, 2, 480, 480);
frame.add(panel);
frame.revalidate(); // Repaint here!! Removing these calls
frame.repaint(); // demonstrates the problem you are having.
}
});
frame.add(button);
frame.setSize(695, 482);
frame.setVisible(true);
}
}
The above said, (as suggested by others) it's only right that I recommend against the use of a null layout in future. The swing layouts are a little awkward to begin with, but they will help you a great deal in the long run.
the answer can be found in the following snippet:
you need to revalidate() the contentPane, not repaint the frame. you can add any panel you want to the contentpane like this. if you declare contentPane as a private field you dont need your getContentPane() call. contentPane is global so it can be reffered to directly from anywhere within the class.
be careful about NullPointerExeptions which can be thrown if you refer to it before initialising.
public class testframe extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
testframe frame = new testframe();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public testframe() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
setContentPane(contentPane);
JButton btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JPanel a = new JPanel();
contentPane.add(a);
contentPane.revalidate();
}
});
contentPane.add(btnNewButton);
}
}
Is there any good way to change a JFrame opacity real time. right now i need to restart the window to get the opacity
if (Variables.LoggerOpacity){
if (AWTUtilities.isTranslucencySupported(AWTUtilities.Translucency.TRANSLUCENT)) {
AWTUtilities.setWindowOpaque(Frame, true);
AWTUtilities.setWindowOpacity(Frame, 0.60f);
}
}
When i use
AWTUtilities.setWindowOpacity(Frame, 0.60f);
On a button JCheckBox i won't change the opacity.
Q: How can i change the opacity realtime?
Even if you have set the JFrame to static, you should be able to reference it if your opacity method is within the same class, if it isn't - create a getter method to reference your JFrame and pass that to your function. Here's an example program that executes and the opacity works fine:
public class JFrameOpacityExample extends JFrame {
private static JFrame myFrame;
private static boolean loggerOpacity;
private static JButton button;
public static void main(String[] args) {
myFrame = new JFrame("Test Frame");
myFrame.setSize(400, 400);
myFrame.setVisible(true);
JPanel panel = new JPanel();
button = new JButton("Press me");
button.setBounds(100, 100, 50, 50);
button.setVisible(true);
panel.add(button);
myFrame.add(panel);
loggerOpacity = true;
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Object src = evt.getSource();
if (src == button && loggerOpacity) {
AWTUtilities.setWindowOpacity(myFrame, 0.40f);
}
}
});
}
}
Add the following command to a frame's constructor. The name of the frame in this example is MyFrame.
jCheckBox1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
AWTUtilities.setWindowOpacity(MyFrame.this, 0.2f);
}
});