java - 在 BorderLayout 面板中堆叠 FlowLayout 面板会导致除 SOUTH 面板之外的所有面板消失?

标签 java swing

我有一个应用程序,我试图在其中将两个 FlowLayout 面板简单地堆叠在一个 BorderLayout 面板内。但是,当我这样做时,两个面板都不可见。

在我尝试堆叠这些面板之前,表单如下所示:

Before Stacking

但是在堆叠它们之后它看起来像这样:

After Stacking

当使用SSCCE时,导致问题的行是这一行:

pane.add(textAreaPanel, BorderLayout.CENTER);

因此,如果您评论该行,表单至少会显示第一个面板。

中南合作中心

家教计算器

package tutoringcalculator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.*;
import javax.swing.*;

public class TutoringCalculator extends JFrame {
    FlowLayout layout = new FlowLayout(FlowLayout.LEFT);

    public TutoringCalculator(String name) {
        super(name);
    }

    public void addComponentsToPane(final Container pane) {
        final JPanel contentPanel = new JPanel();
        contentPanel.setLayout(layout);
        final JPanel textAreaPanel = new JPanel();
        textAreaPanel.setLayout(layout);
        final JPanel buttons = new JPanel();
        buttons.setLayout(new FlowLayout(FlowLayout.RIGHT));

        contentPanel.add(new JLabel("Session Minutes:"));

        JTextField txt = new JTextField(10);
        txt.setName("sessionMinutes");

        txt.addFocusListener(new DecimalFieldFocusListener(new IValidDecimalValue() {
            @Override
            public boolean callback(String val) {
                return ApplicationState.getInstance().setCurrentSessionMinutes(val);
            }
        }));
        contentPanel.add(txt);

        // setup the default border
        ApplicationState.getInstance().setDefaultTextFieldBorder(txt.getBorder());

        contentPanel.add(new JLabel("Earnings:"));

        txt = new JTextField(10);
        txt.setName("earnings");

        txt.addFocusListener(new DecimalFieldFocusListener(new IValidDecimalValue() {
            @Override
            public boolean callback(String val) {
                return ApplicationState.getInstance().setCurrentEarnings(val);
            }
        }));
        contentPanel.add(txt);

        JButton btn = new JButton("Enter");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String result = ApplicationState.getInstance().acceptEarnings();
                if (result != null) {
                    JOptionPane.showMessageDialog(null, result, "Error Entering Earnings", JOptionPane.ERROR_MESSAGE);
                }
                else {
                    JOptionPane.showMessageDialog(null, "The session minutes and earnings were accepted.", "Success!", JOptionPane.INFORMATION_MESSAGE);

                    JTextField sessionMinutes = (JTextField)contentPanel.getComponent(1);
                    sessionMinutes.setText("");

                    JTextField earnings = (JTextField)contentPanel.getComponent(3);
                    earnings.setText("");

                    sessionMinutes.requestFocus();
                }
            }
        });
        contentPanel.add(btn);

        JTextArea textArea = new JTextArea();
        textAreaPanel.add(textArea);

        btn = new JButton("Run Report");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
            }
        });
        buttons.add(btn);

        btn = new JButton("Quit");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        buttons.add(btn);

        pane.add(contentPanel, BorderLayout.CENTER);
        pane.add(textAreaPanel, BorderLayout.CENTER);
        pane.add(buttons, BorderLayout.SOUTH);
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        TutoringCalculator frame = new TutoringCalculator("Tutoring Calculator");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        //Set up the content pane.
        frame.addComponentsToPane(frame.getContentPane());
        //Display the window.
        frame.setPreferredSize(new Dimension(600, 400));
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        /* Use an appropriate Look and Feel */
        try {
            //UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
        } catch (UnsupportedLookAndFeelException | IllegalAccessException | InstantiationException | ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        /* Turn off metal's use of bold fonts */
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        //Schedule a job for the event dispatchi thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

应用状态

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tutoringcalculator;

import javax.swing.border.Border;

/**
 *
 * @author Owner
 */
final public class ApplicationState {
    private static ApplicationState instance = new ApplicationState();
    public static ApplicationState getInstance() {
        return instance;
    }

    private ApplicationState() {

    }

    private Border defaultTextFieldBorder;
    public Border getDefaultTextFieldBorder() {
        return defaultTextFieldBorder;
    }
    public void setDefaultTextFieldBorder(Border b) {
        defaultTextFieldBorder = b;
    }

    private double currentSessionMinutes;
    private boolean isValidSessionMinutes;
    public boolean setCurrentSessionMinutes(String text) {
        isValidSessionMinutes = false;
        try {
            currentSessionMinutes = Double.parseDouble(text);
            isValidSessionMinutes = true;
        }
        catch (NumberFormatException nfe) {
            return false;
        }

        return true;
    }

    private double currentEarnings;
    private boolean isValidCurrentEarnings;
    public boolean setCurrentEarnings(String text) {
        isValidCurrentEarnings = false;
        try {
            currentEarnings = Double.parseDouble(text);
            isValidCurrentEarnings = true;
        }
        catch (NumberFormatException nfe) {
            return false;
        }

        return true;
    }

    public String acceptEarnings() {
        if (!(isValidSessionMinutes && isValidCurrentEarnings)) {
            return "Please enter valid session minutes and current earnings.";
        }

        addEarnings(currentSessionMinutes, currentEarnings);

        return null;
    }

    private double[][] earningsArray = new double[100][2];
    private int newRowIndex = 0;
    private void addEarnings(double sessionMinutes, double earnings) {
        earningsArray[newRowIndex][0] = sessionMinutes;
        earningsArray[newRowIndex][1] = earnings;
        newRowIndex++;
    }
}

DecimalFieldFocusListener

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tutoringcalculator;

import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BorderFactory;
import javax.swing.JTextField;

/**
 *
 * @author Owner
 */
public class DecimalFieldFocusListener implements FocusListener {
    private IValidDecimalValue _callback;

    public DecimalFieldFocusListener(IValidDecimalValue callback) {
        _callback = callback;
    }

    public void focusGained(FocusEvent e) {
    }

    public void focusLost(FocusEvent e) {
        JTextField txt = (JTextField)e.getSource();
        if (!_callback.callback(txt.getText())) {
            txt.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.red));
        }
        else {
            txt.setBorder(ApplicationState.getInstance().getDefaultTextFieldBorder());
            txt.setBackground(Color.white);
        }
    }
}

IValidDecimalValue

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tutoringcalculator;

/**
 *
 * @author Owner
 */
public interface IValidDecimalValue {
    boolean callback(String val);
}

最佳答案

BorderLayout.CENTER 位置只能出现一个组件。因此当

pane.add(contentPanel, BorderLayout.CENTER);
pane.add(textAreaPanel, BorderLayout.CENTER);

被调用时,textAreaPanel 有效地取代了 contentPanel。相反,您可以将 contentPanel 放在 NORTH 位置:

pane.add(contentPanel, BorderLayout.NORTH);

关于java - 在 BorderLayout 面板中堆叠 FlowLayout 面板会导致除 SOUTH 面板之外的所有面板消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16598968/

相关文章:

java - 在 Lucene 中对词级注释层进行索引和搜索

java - 为什么 while 循环中的 if 语句仅在调试时执行?

java - 如何在Ubuntu中打开终端并使用Java代码向其传递参数?

java - 尝试在 GUI 中使用 Jpanel 进行绘制

java - 在 JTextPane 中编辑文本时出现空指针异常

java - 来自 Java 源错误 : cannot find symbol 的 Grails 域类方法

java - 使用 Travis CI 分析 SonarQube.com 上的 Java Gradle 项目

java - 根据字符串的宽度绘制动态按钮

JAVA 将 Socket 包装为多屏 Swing 应用程序中的 Singleton 类

java - 帮助编写您自己的 javax.swing.text.Document