JDialog not centered over parent JFrame - java

I am trying to get my JDialog to popup in the center of my JFrame on a button click. I have JOptionPanel that popup correctly over the parent JFrame, but the JDialog is popping up relative to the JFrame but not in the center.
The buttons are actually JMenuItem in my code, but I wrote them here as JButton to make things easier and straight forward.
Here's my code:
call from my Parent JFrame:
JButton about = new JButton("About");
about.addActionListener(new ActionListener() { //this one IS NOT in the center of MyJFrame
public void actionPerformed(ActionEvent e) {
new AboutDialog(MyJFrame.this);
}
});
JButton exit = new JButton("Exit");
exit.addActionListener(new ActionListener() { //this one IS in the center of MyJFrame
public void actionPerformed(ActionEvent e) {
if(JOptionPane.showConfirmDialog(MyJFrame.this, "Are you sure you want to exit ?","",JOptionPane.YES_NO_OPTION) == 0)
System.exit(0);
}
});
AboutDialog Class
public class AboutDialog extends JDialog{
public AboutDialog(JFrame parent) {
setLocationRelativeTo(parent);
setLayout(new BorderLayout());
...
Thank you

setLocationRelativeTo(parent);
The above code needs to be executed AFTER you have added all the components to the dialog and packed the dialog and before you make the dialog visible.
In your current code the size of the dialog is (0, 0) so it can't be centered properly.

Related

Close windows without closing Application

Good afternoon!
I have this code:
private static class ClickListener implements ActionListener {
public ClickListener() {
}
#Override
public void actionPerformed(ActionEvent e) {
JFrame frame = new JFrame();
JLabel label = new JLabel("Opção Indisponivel");
JPanel panel = new JPanel();
frame.add(label, BorderLayout.CENTER);
frame.setSize(300, 400);
JButton button = new JButton("Voltar");
button.addActionListener(new CloseWindowListener());
panel.add(button);
frame.add(panel, BorderLayout.SOUTH);
frame.setVisible(true);
}
}
private static class CloseWindowListener implements ActionListener {
public CloseWindowListener() {
}
#Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
}
What I want to do is when i click on the button "voltar" (which is in another window, not on the "main" one as you can see) it closes the windows but not the app itselft. The setVisible line gives me an error about that it cannot be referenced by a static context which I understand because I need the reference of the frame. How do I solve this?
EDIT: Changed JFrame to JDialog but still no sucess. Both windows are shutdown.
Thanks in advance,
Diogo Santos
The setVisible line gives me an error about that it cannot be referenced by a static context which I understand because I need the reference of the frame. How do I solve this?
You can access the component that generated the event. Then you can find the window the component belongs to. This will give you generic code to hide any window:
//setVisible(false);
JButton button = (JButton)e.getSource();
Window window = SwingUtilities.windowForComponent(button);
window.setVisible(false);
You can also check out Closing an Application. The ExitAction can be added to your button. Now when you click the button it will be like clicking the "x" (close) button of the window. That is whatever default close operation your specify for the window will be invoked.

JPanel doesn't update when adding Component in another class

I'm fairly new to Java Swing and I'm running into a few problems.
As a side question, when making a fairly large Java Swing Application, what is the best way to split up code?
In my case I want to have an application that has a layout just as Microsoft Word where there is a JToolBar filled with buttons and a main JPanel where changes are made based on the buttons pressed in the Tool Bar.
So as shown in the code below, I have a JFrame and I call the MainPanel class in order to create a panel and add a ToolBar with a button. When the button is pressed it adds a button to the panel. The problem comes when you click the button nothing shows up until you resize the window(in my case I simply manually drag the screen to make it larger).
public class Main {
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("MathMaker");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create the menu bar. Make it have a green background.
//MainToolBar mainTB = new MainToolBar();
MainPanel mainPanel = new MainPanel();
frame.getContentPane().add(mainPanel.getGUI(), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
public class MainPanel implements ActionListener{
JPanel mPanel;
JToolBar mToolBar;
JButton addQuestion;
public MainPanel() {
mPanel = new JPanel(new BorderLayout());
mToolBar = new JToolBar();
addQuestion = new JButton("test");
addQuestion.addActionListener(this);
mPanel.setLayout(new BorderLayout());
mPanel.setBackground(new Color(248, 213, 131));
mPanel.setPreferredSize(new Dimension(200, 180));
mToolBar.add(addQuestion);
mPanel.add(mToolBar, BorderLayout.PAGE_START);
}
public JComponent getGUI()
{
return mPanel;
}
#Override
public void actionPerformed(ActionEvent e) {
JButton temp = new JButton("temp");
mPanel.add(temp);
}
}
You should revalidate your panel
#Override
public void actionPerformed(ActionEvent e) {
JButton temp = new JButton("temp");
mPanel.add(temp);
mPanel.revalidate();
mPanel.repaint();
}
I believe you need to call revalidate() and repaint() to see the changes, here is a similar question here
The problem here is the panel is not repainted automatically.. When you resize the panel Java repaints the panel on the screen. Try repainting the panel everytime any button to modify the panel is clicked..
Just call the validate() and repaint() method with the panel

Java GUI panel unable to refresh?

I have 3 panels in the frame, panel, panel1, panel2. When I click on the button it doesn't remove the panel from the frame.
private class ButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)
{
// some stuffs here.
++current;
frame.remove(panel1);
frame.revalidate();
frame.repaint();
}
}
edit: i used this too but it doesn't work as well
frame.remove(panel1);
frame.getContentPane().invalidate();
frame.getContentPane().validate();
frame.getContentPane().repaint();

Java keep frame focused

Could you please help me on this one? I have a JDialog with some textfields, checkboxes and buttons. I want that when the frame is not focused anymore, to disappear. So I added a focus listener to the JDialog and when the focus is lost, I call dialog.setVisible(false);. The problem is that if I click on the checkbox,textfield or button, the frame loses it's focus and disappears. How could I keep it focused until the user clicks outside it's area?
EDIT : The "frame" I am referring to is a JDialog. I don't use a Frame nor a JFrame. All the components are placed on the JDialog. I want it to hide when not focused, but keep it focused until the user clicks outside it's area.
Seems like you had added the wrong Listener, what you should be adding is addWindowFocusListener(...), see this small sample program, is this what you want to happen :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DialogFocus
{
private JFrame frame;
private MyDialog myDialog;
public DialogFocus()
{
}
private void createAndDisplayGUI()
{
frame = new JFrame("JFRAME");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
myDialog = new MyDialog(frame, "My Dialog", false);
JButton showButton = new JButton("SHOW DIALOG");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (!(myDialog.isShowing()))
myDialog.setVisible(true);
}
});
frame.add(showButton, BorderLayout.PAGE_END);
frame.setSize(300, 300);
frame.setVisible(true);
}
public static void main(String\u005B\u005D args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new DialogFocus().createAndDisplayGUI();
}
});
}
}
class MyDialog extends JDialog
{
private WindowFocusListener windowFocusListener;
public MyDialog(JFrame frame, String title, boolean isModal)
{
setTitle(title);
setModal(isModal);
JPanel contentPane = new JPanel();
JTextField tfield = new JTextField(10);
JComboBox cbox = new JComboBox();
cbox.addItem("One");
cbox.addItem("Two");
cbox.addItem("Three");
contentPane.add(tfield);
contentPane.add(cbox);
windowFocusListener = new WindowFocusListener()
{
public void windowGainedFocus(WindowEvent we)
{
}
public void windowLostFocus(WindowEvent we)
{
setVisible(false);
}
};
addWindowFocusListener(windowFocusListener);
add(contentPane);
pack();
}
}
Make the dialog modal, then the user cannot click on the frame.
Check the FocusEvent
it has public Component getOppositeComponent(). If the opposite component is child component of the JDialog don't hide the dialog.

Detect removal of component

I create a Popup using the PopupFactory.getPopup method. According to the documentation, I am required to call the hide() method on the popup when it is no longer needed.
In my application, the popup is the child of a JLabel which may be removed from the current frame in a number of different situations. (Either the JLabel itself or one of its parent containers is removed.) Rather that calling hide() in every single place (and making the Popup object available in all these places) I would prefer to be able to detect the removal of the JLabel or one of its parent containers.
How can I detect the removal? I naively assumed that the removal of a component meant the removal/hiding of its children, but as the code below shows, the popup survives the removal of the JLabel.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Xyzzy extends JFrame {
static Xyzzy frame;
static JPanel panel;
static JLabel text1;
static JLabel text2;
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new Xyzzy();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.PAGE_AXIS));
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
frame.add(panel);
text1 = new JLabel("text1");
text2 = new JLabel("text2");
panel.add(text1);
frame.add(new JButton(new AbstractAction("Add popup") {
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
popup.show();
}
}));
frame.add(new JButton(new AbstractAction("New label") {
public void actionPerformed(ActionEvent e) {
panel.remove(text1);
panel.add(text2);
panel.revalidate();
}
}));
frame.setSize(600, 600);
frame.setVisible(true);
}
});
}
}
This code creates a JFrame displaying the text "text1" and two buttons. If you press the button labeled "Add popup", a Popup with the text "POPUP" appears in the window. This Popup is a child of text1. Press the "New label" button and "text1" is removed from the display, but the Popup survives.
I need to be able to detect when text1 or the containing panel is removed so that I can hide the popup. I want to avoid adding code where the actual remove() method is called.
You can use HierarchyListener:
public void actionPerformed(ActionEvent e) {
PopupFactory factory = PopupFactory.getSharedInstance();
final Popup popup = factory.getPopup(text1, new JLabel("POPUP"),frame.getX()+300,frame.getY()+300);
text1.addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
if (e.getID() == HierarchyEvent.HIERARCHY_CHANGED
&& (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
popup.hide();
}
}
});
popup.show();
}

Categories

Resources