1

I really don't understand what is happening here. I have a program that I would like to use a JDialog in, but I wanted a separate class for it so I extended the class for a JDialog, went to set the preferred size of it, but it doesn't appear to be setting it correctly. I make a button to "cancel" the operation the JDialog will do that is supposed to be in the bottom right of the JDialog, but it doesn't go there. It instead is outside of it, and only shows up once I resize the JDialog.

I don't have the slightest clue what's going on, or if I'm missing something stupid, but any help is appreciated.

Here is the code:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class NewPlatformDialog extends JDialog implements ActionListener {
private LevelEditor le;

private JButton cancel = new JButton("cancel");

public NewPlatformDialog(Frame owner, String title, LevelEditor l) {
    super(owner, title, Dialog.ModalityType.APPLICATION_MODAL);
    le = l;
    setLayout(null);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setPreferredSize(new Dimension(300, 200));

    add(cancel);
    setLocation((owner.getLocationOnScreen().x + (owner.getLocationOnScreen().x + owner.getWidth()))/2 - getPreferredSize().width/2
            , (owner.getLocation().y + (owner.getLocationOnScreen().y + owner.getHeight()))/2 - getPreferredSize().height/2);

    cancel.setBounds(getPreferredSize().width - cancel.getPreferredSize().width - 10, 
            getPreferredSize().height - cancel.getPreferredSize().height - 10,
            cancel.getPreferredSize().width, cancel.getPreferredSize().height);
    cancel.addActionListener(this);
    cancel.setFocusable(false);

    pack();
    setVisible(true);
}

public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if(source == cancel) dispose();
}
}

Sorry it is a little messy, it gets a little screwed up when I copy paste it.

UPDATED CODE WITH LAYOUTS

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class NewPlatformDialog extends JDialog implements ActionListener {
private LevelEditor le;
private String[] options = {
        "Standard Platform",
        "Boost Platform",
        "Moving Platform",
        "Death Platform"
};
private JComboBox<String> platformSelector = new JComboBox<String>(options);

private JButton cancel = new JButton("cancel");

CardLayout cl = new CardLayout();

private JPanel typeSelect = new JPanel(new FlowLayout(FlowLayout.LEFT));
private JPanel panelContainer = new JPanel();
private JPanel standardPlatform = new JPanel();
private JPanel boostPlatform = new JPanel();
private JPanel movingPlatform = new JPanel();
private JPanel deathPlatform = new JPanel();
private JPanel buttonPanel = new JPanel();

public NewPlatformDialog(Frame owner, String title, LevelEditor l) {
    super(owner, title, Dialog.ModalityType.APPLICATION_MODAL);
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
    setResizable(false);

    cl.setVgap(10);
    panelContainer.setLayout(cl);
    le = l;

    platformSelector.addActionListener(this);
    platformSelector.setFocusable(false);
    platformSelector.setSize(100, 70);
    platformSelector.setFont(new Font("", Font.BOLD, 12));
    platformSelector.setMaximumSize(new Dimension(200, platformSelector.getPreferredSize().height));
    platformSelector.setMinimumSize(new Dimension(200, platformSelector.getPreferredSize().height));

    add(typeSelect);
    add(panelContainer);
    add(buttonPanel);

    panelContainer.add(standardPlatform, "1");
    panelContainer.add(boostPlatform, "2");
    panelContainer.add(movingPlatform, "3");
    panelContainer.add(deathPlatform, "4");
    panelContainer.setMaximumSize(new Dimension(500, 500));
    panelContainer.setMinimumSize(new Dimension(20, 20));

    createTypeSelect();
    createStandardPlatformPanel();
    createButtonPanel();

    cl.show(panelContainer, "1");

    pack();
    setVisible(true);
}

public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if(source == cancel) dispose();
    else if(source == platformSelector) {
        if(platformSelector.getSelectedIndex() == 0) {
            cl.show(panelContainer, "1");
            createStandardPlatformPanel();
        }
        else if(platformSelector.getSelectedIndex() == 1) {
            cl.show(panelContainer, "2");
            createBoostPlatformPanel();
        }
        else if(platformSelector.getSelectedIndex() == 2) {
            cl.show(panelContainer, "3");
            createMovingPlatformPanel();
        }
        else if(platformSelector.getSelectedIndex() == 3) {
            cl.show(panelContainer, "4");
            createDeathPlatformPanel();
        }
    }
}

private void createTypeSelect() {
    typeSelect.add(new JLabel("Platform Type: ")).setFont(new Font("", Font.PLAIN, 14));
    typeSelect.add(platformSelector);
}

private void createStandardPlatformPanel() {
    panelContainer.setPreferredSize(new Dimension(200, 200));
    standardPlatform.setBackground(Color.BLUE);
    pack();
}

private void createBoostPlatformPanel() {
    panelContainer.setPreferredSize(new Dimension(500, 500));
    boostPlatform.setBackground(Color.RED);
    pack();
}

private void createMovingPlatformPanel() {
    panelContainer.setPreferredSize(new Dimension(50, 50));
    movingPlatform.setBackground(Color.YELLOW);
    pack();
}

private void createDeathPlatformPanel() {
    panelContainer.setPreferredSize(new Dimension(100, 100));
    deathPlatform.setBackground(Color.GRAY);
    pack();
}

private void createButtonPanel() {
    cancel.addActionListener(this);
    cancel.setFocusable(false);
    cancel.setAlignmentX(Box.RIGHT_ALIGNMENT);
    buttonPanel.add(cancel);
}

/*
 * 
    add(cancel);
    setLocation((owner.getLocationOnScreen().x + (owner.getLocationOnScreen().x + owner.getWidth()))/2 - getPreferredSize().width/2
            , (owner.getLocation().y + (owner.getLocationOnScreen().y + owner.getHeight()))/2 - getPreferredSize().height/2);

    cancel.setBounds(getPreferredSize().width - cancel.getPreferredSize().width - 10, 
            getPreferredSize().height - cancel.getPreferredSize().height - 10,
            cancel.getPreferredSize().width, cancel.getPreferredSize().height);
    cancel.addActionListener(this);
    cancel.setFocusable(false);
 */
}

Sorry it's significantly more

Ryan
  • 727
  • 2
  • 14
  • 31
  • If you want it to be that size, why not just use `setSize`? Or, preferably, use a layout manager and let it handle choosing a size. – resueman Jul 07 '16 at 22:06
  • `set size` doesn't work either, and I setLayout to null so I could place my components more precisely – Ryan Jul 07 '16 at 22:09
  • 1
    `setLayout(null);` I recommend against using null layouts - choose a LayoutManager that fits your needs. – copeg Jul 07 '16 at 22:23
  • @copeg Ok, but that still doesn't fix my problem. I have set the layout of several components to null several times before, I shouldn't be getting this problem – Ryan Jul 07 '16 at 22:27
  • @Ryan `that still doesn't fix my problem` I recommend an update of the posted code to show the use of a Layout, and describe how you wish your layout to be vs what you have. Trust me, avoid null layouts like the plague - it may display different from one computer to the next, and can be impossible to modify. – copeg Jul 07 '16 at 22:31

1 Answers1

2

The problem is happening because the preferred size of a dialog includes the title bar of the window, as well as any other window decorations. However, the location within the window is set from the upper left corner of the content pane. Because of that difference, most window managers will have your button end up a little too far right, and a lot too far down.

The correct solution is to use actual layout managers, which will correctly position your components. Here's an example which puts the button where you want:

setLayout(new BorderLayout());
JPanel bottom = new JPanel();
bottom.setLayout(new BorderLayout());
bottom.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
bottom.add(new JPanel(), BorderLayout.CENTER);
bottom.add(cancel, BorderLayout.EAST);
add(new JPanel(), BorderLayout.CENTER);
add(bottom, BorderLayout.SOUTH);

If you're insistent on using a null layout, you can change your code to use getContentPane().setPreferredSize(new Dimension(300, 200)) instead, which will let your frame add the necessary space for the window decorations. However, I would strongly advise you not to do this. Using a null layout is considered a bad practice.

Community
  • 1
  • 1
resueman
  • 10,572
  • 10
  • 31
  • 45
  • Thank you. And I have begun to look at using different layout managers as a substitute, but it is nice to know how to fix this if I do something like it in the future – Ryan Jul 08 '16 at 00:15
  • Also, if I may ask you a quick question, how familiar are you with BoxLayouts and CardLayouts. It's what I began working on, and I'm getting close to it looking like the what I want more or less, but I have one or two questions on it. I'm going to post my current code regardless though – Ryan Jul 08 '16 at 00:26
  • 1
    @Ryan `CardLayout`s are pretty straightforward. I'm less familiar with `BoxLayout`s, but might be able to answer it. What are your questions? – resueman Jul 08 '16 at 00:55
  • Ok thanks. One of my question is I have the JPanels in the middle of the BoxLayout(but the CardLayout controls which JPanel is showing), and I'm having trouble resizing the JPanel correctly. I've managed to get it to change the width, but it seems to be doing the height wrong, and I'm unsure why. From the research I've done I believe I'm doing it correctly. – Ryan Jul 08 '16 at 01:01
  • I clearly didn't do enough research, because I quickly found out part of the reason. It is the type of the layout `BoxLayout.Y_AXIS` which respects when I set the width, but not the height, and vice versa with `BoxLayout.X_AXIS`. The thing I don't know how to do, is how to get around it. I may be able to just ignore it and still be able to achieve what I want, but I'd rather see if there is a way around it. – Ryan Jul 08 '16 at 01:10
  • Actually don't worry about it, I have things set up just the way I want now. Thanks again for all your help – Ryan Jul 08 '16 at 02:14