2016-10-22 9 views
1

Я создал класс под названием CreateNewGraph, который расширяет JDialog, и этот класс вызывается из отдельного класса. В первый раз, когда он вызывается, он ведет себя так, как ожидалось, но в любое время после этого макет (я использую MigLayout) становится все испорченным: компоненты не распределены правильно, и каждый компонент добавляется дважды.JDialog имеет различное поведение каждый раз, когда он создан

Извините заранее за столько кода, я хочу включить его все, потому что я не знаю, где проблема.

Вот код для CreateNewGraph:

public class CreateNewGraph extends JDialog { 

private static final JPanel contentPanel = new JPanel(); 
private static JPanel buttonPanel; 
private static JTextField txtFldName; 
private static Font directionFont = new Font("TimesRoman", Font.PLAIN, 15); 
private static JTextPane txtPaneTypeError, txtPaneNameError, txtPaneEnterName; 
private static JButton okButton, cancelButton; 
private static JRadioButton rdbtnXYGraph, rdbtnTimeGraph; 
private static ButtonGroup kind; 
private static JLabel lblWhichKind, lblName; 

/** 
* Create the dialog. 
*/ 
public CreateNewGraph() { 
    setTitle("Add a New Graph"); 
    setModalityType(ModalityType.APPLICATION_MODAL); 
    setModal(true); 
    setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
    setBounds(100, 100, 450, 300); 
    getContentPane().setLayout(new BorderLayout()); 

    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); 
    getContentPane().add(contentPanel, BorderLayout.CENTER); 
    contentPanel.setLayout(new MigLayout("", "[grow]", "[][][][][][][grow][grow]")); 

    lblWhichKind = new JLabel("What kind of graph would you like to add? You may select only one."); 
    lblWhichKind.setFont(directionFont); 
    contentPanel.add(lblWhichKind, "cell 0 0"); 

    kind = new ButtonGroup(); 

    Component strutRadioBtns = Box.createHorizontalStrut(20); 
    contentPanel.add(strutRadioBtns, "flowx,cell 0 1"); 

    rdbtnXYGraph = new JRadioButton("XY Graph"); 
    contentPanel.add(rdbtnXYGraph, "cell 0 1"); 
    kind.add(rdbtnXYGraph); 

    rdbtnTimeGraph = new JRadioButton("Time Graph"); 
    contentPanel.add(rdbtnTimeGraph, "cell 0 1"); 
    kind.add(rdbtnTimeGraph); 

    Component verticalStrut = Box.createVerticalStrut(10); 
    contentPanel.add(verticalStrut, "cell 0 2"); 

    txtPaneEnterName = new JTextPane(); 
    txtPaneEnterName.setText("What would you like to name this graph? It must be a unique name (you may not use one you have already used.)"); 
    txtPaneEnterName.setFont(directionFont); 
    txtPaneEnterName.setEditable(false); 
    txtPaneEnterName.setOpaque(false); 
    contentPanel.add(txtPaneEnterName, "cell 0 3,grow"); 

    Component horizontalStrut = Box.createHorizontalStrut(20); 
    contentPanel.add(horizontalStrut, "flowx,cell 0 4"); 

    lblName = new JLabel("Name:"); 
    contentPanel.add(lblName, "cell 0 4"); 

    txtFldName = new JTextField(); 
    contentPanel.add(txtFldName, "cell 0 4"); 
    txtFldName.setColumns(10); 

    Component verticalStrut_1 = Box.createVerticalStrut(10); 
    contentPanel.add(verticalStrut_1, "cell 0 5"); 

    txtPaneTypeError = new JTextPane(); 
    txtPaneTypeError.setText("Graph Type Error: "); 
    txtPaneTypeError.setEditable(false); 
    txtPaneTypeError.setOpaque(false); 
    contentPanel.add(txtPaneTypeError, "cell 0 6,grow"); 

    txtPaneNameError = new JTextPane(); 
    txtPaneNameError.setText("Graph Name Error: "); 
    txtPaneNameError.setEditable(false); 
    txtPaneNameError.setOpaque(false); 
    contentPanel.add(txtPaneNameError, "cell 0 7,grow"); 

    buttonPanel = new JPanel(); 
    buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); 
    getContentPane().add(buttonPanel, BorderLayout.SOUTH); 

    okButton = new JButton("OK"); 
    okButton.setActionCommand("OK"); 
    buttonPanel.add(okButton); 

    cancelButton = new JButton("Cancel"); 
    buttonPanel.add(cancelButton); 
    getRootPane().setDefaultButton(cancelButton); 
} 

У меня также есть ActionListener сек на каждую кнопке, но я удалил те, ради краткости. Как правило, я не отправил бы это много кода, но я не уверен, где происходит ошибка

И, код я использую в другом классе, чтобы создать экземпляр CreateNewGraph (исключения не выбрасываются.):

EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        try { 
         CreateNewGraph add = new CreateNewGraph(); 
         add.setVisible(true); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      }); 

Это то, что происходит, когда он открывает в первый раз: First time

Это первый случай, именно то, что он должен выглядеть. Но второй раз, это происходит: Second time small Это второй случай, расширяется, чтобы заполнить мой экран: Second time full

+0

Shannon - вы создаете их один раз в качестве статических полей, но повторно используете их и повторно добавляете их каждый раз, когда вы создаете диалог. Это испортит макет. –

ответ

3

Ты убиваешь себя со статическими компонентами, которые повторно добавлены в статические JPanel, которые губят ваш графический интерфейс. Решение: введите все поля экземпляров полей класса JDialog. Это позволит вам создавать их заново при создании объектов, поэтому вы не разрушаете свой макет. Дополнительным бонусом является то, что вы также будете следовать хорошей практике ООП.

+0

Спасибо, что исправил проблему. Почему статические поля все испортили? Я понял, что поскольку 'dispose()' вызывался в каждом JDialog после его использования, переменные были бы сброшены (если вы знаете, что я имею в виду, я не уверен в правильной терминологии, чтобы использовать там.) – Shannon

+0

@Shannon: dispose только распоряжается системными ресурсами. Статические поля и объекты, которые они ссылаются, все еще существуют. И действительно, статика здесь просто не имеет никакого смысла. –