2016-07-07 10 views
1

Я действительно не понимаю, что здесь происходит. У меня есть программа, в которой я хотел бы использовать JDialog, но мне нужен отдельный класс для этого, поэтому я расширил класс для JDialog, пошел, чтобы установить его предпочтительный размер, но он, похоже, не устанавливает его правильно. Я делаю кнопку «отменить» операцию, которую будет выполнять JDialog, которая должна находиться в правом нижнем углу JDialog, но она не идет туда. Вместо этого он выходит за его пределы и появляется только после изменения размера JDialog.JDialog не устанавливает предпочтительный размер правильно?

У меня нет ни малейшего понятия, что происходит, или если мне не хватает чего-то глупого, но любая помощь приветствуется.

Вот код:

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(); 
} 
} 

К сожалению, это немного грязный, он получает немного облажался, когда я копирую вставить.

ОБНОВЛЕНО КОД макеты

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); 
*/ 
} 

К сожалению, это значительно более

+0

Если вы хотите, чтобы это был такой размер, почему бы просто не использовать 'setSize'? Или, желательно, используйте диспетчер компоновки и пусть он обрабатывает выбор размера. – resueman

+0

'set size' тоже не работает, и я установилLayout равным null, чтобы я мог точнее разместить мои компоненты – Ryan

+1

' setLayout (null); 'Я рекомендую не использовать нулевые макеты - выберите LayoutManager, который соответствует вашим потребностям. – copeg

ответ

2

Проблема происходит потому, что предпочтительный размер диалога включает в себя строку заголовка окна, а также любое другое окно украшения. Однако местоположение в окне устанавливается из верхнего левого угла области содержимого . Из-за этой разницы большинство оконных менеджеров будут иметь вашу кнопку в конечном итоге слишком далеко правее, и слишком сильно вниз.

Правильное решение заключается в использовании фактических менеджеров компоновки, которые правильно позиционируют ваши компоненты. Вот пример, который ставит на кнопку, где вы хотите:

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); 

Если вы настойчивы в использовании null макета, вы можете изменить код, чтобы использовать getContentPane().setPreferredSize(new Dimension(300, 200)) вместо этого, что позволит фоторамке добавить необходимое пространство для оконные украшения. Тем не менее, я бы сильно советую вам не делать этого. Использование макета null - considered a bad practice.

+0

Спасибо. И я начал рассматривать использование разных менеджеров макетов в качестве замены, но хорошо знать, как это исправить, если я буду делать что-то в этом роде – Ryan

+0

Кроме того, если я могу задать вам быстрый вопрос, насколько вы знакомы с BoxLayouts и CardLayouts. Это то, над чем я начал работать, и приближаюсь к нему, похоже на то, что хочу больше или меньше, но у меня есть один или два вопроса. Я собираюсь опубликовать свой текущий код, несмотря на то, что – Ryan

+1

@Ryan 'CardLayout' довольно просты. Я менее знаком с «BoxLayout's», но мог бы ответить на него. Какие у вас вопросы? – resueman