javagui-嵌套面板

javagui-嵌套面板,java,swing,jpanel,Java,Swing,Jpanel,我正在尝试制作一个表单,该表单接受用户输入的名字和姓氏,并打印一条欢迎消息,将两者结合起来。我想将输入内容组合到一个网格面板中,然后将“Go”按钮和在另一个面板中显示消息的文本字段组合在一起,并在一个框架内使用BorderLayout将它们嵌套在一起 一般布局: (在3x2网格中) “转到”按钮“欢迎Mark Summers” 教授想把它全部放在一个.java文件中,这是我的问题。我通常会把这些东西分开,然后扩展类,这样就没有问题了。我要做的是将输入和输出面板保存在构造函数下,然后保存在main

我正在尝试制作一个表单,该表单接受用户输入的名字和姓氏,并打印一条欢迎消息,将两者结合起来。我想将输入内容组合到一个网格面板中,然后将“Go”按钮和在另一个面板中显示消息的文本字段组合在一起,并在一个框架内使用BorderLayout将它们嵌套在一起

一般布局:

(在3x2网格中)

“转到”按钮“欢迎Mark Summers”

教授想把它全部放在一个.java文件中,这是我的问题。我通常会把这些东西分开,然后扩展类,这样就没有问题了。我要做的是将输入和输出面板保存在构造函数下,然后保存在main下的create

JFrame frame = new JFrame();
然后

add(new CalebBreckonHW3(320,120));
因此,在我的700x700 JFrame“frame”中放置了一个320x120面板。我收到一条错误消息,尽管我不能从静态上下文中引用非静态方法add(java.awt.Component)。我无法将main设置为非静态,否则会出错

我正在通过一个新的程序向这个程序添加代码,有人能给我指出正确的方向吗

import java.awt.*;
import javax.swing.*;

public class CalebBreckonHW3 extends JFrame {
    private JButton jbtGreet = new JButton("Greet Me");
    private JLabel firstOprLbl = new JLabel("First name");
    private JLabel lastOprLbl = new JLabel("Last name");
    private JLabel ageOprLbl = new JLabel("Age");
    private JTextField jtfFirst = new JTextField(10);
    private JTextField jtfLast = new JTextField(15);
    private JTextField jtfAge = new JTextField(3);
    // I'll get to the action events after I get this down
    private JTextField jtfGreet = new JTextField("Welcome firstname, lastname");

    public CalebBreckonHW3(int height, int width) {
        setLayout(new BorderLayout());
        setSize(height, width);
        JPanel inputPanel = new JPanel();
        inputPanel.setLayout(new GridLayout(3,2,0,5));
        jtfGreet.setEditable(false);
        inputPanel.add(firstOprLbl);
        inputPanel.add(jtfFirst);
        inputPanel.add(lastOprLbl);
        inputPanel.add(jtfLast);
        inputPanel.add(ageOprLbl);
        inputPanel.add(jtfAge);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Greeting App");
        frame.setSize(700,700);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        add(new CalebBreckonHW3(320,120));
    }
}

编辑:在add语句前面添加frame可以消除静态错误,但它会给我一个错误“将窗口添加到容器”

问题是您从类中扩展了
JFrame
类,但是您在
main()
中启动了自己的
JFrame
,并且您不能调用
add()
因为您处于main中,这是
静态的
,而
add()
需要在调用前创建一个实例,请参阅我对您的问题的评论,但是,您不应该扩展
JFrame
,而应该:

public class CalebBreckonHW3  {

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
        JFrame frame = new JFrame();
        frame.setTitle("Greeting App");
       // frame.setSize(700,700); //not recommened
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         JPanel panel=new JPanel(/*set layout if needed*/); 
         //panel.add(new JButton("Hello")); //add components to panel

        frame.getContentPane().add(panel);//why did you add your JFrame again???? so I guess you'd wanna add a JPanel or something with the components you need.

        frame.pack();
        frame.setVisible(true);
       }

    });
 }
...
}
还始终创建一个EDT(所有UI组件都位于其上的事件调度线程),我是通过
SwingUtilities.invokeLater()实现的
还始终通过
getContentPane().add()添加到
JFrame
s contentPane。另外,为什么要将Jframe添加到Jframe中?如您所见,我展示了添加
JPanel

编辑:

JFrame
设置为全局变量,然后可以使用
frame.setLayout()

但是,如果希望当前代码正常工作,请执行以下操作:

public class CalebBreckonHW3  extends JFrame{

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
        new CalebBreckonHW3().createandShowUI();
       }

    });
 }
 private void createAndShowUI() {
        setTitle("Greeting App");
        //setSize(700,700); //not recommened
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         JPanel panel=new JPanel(/*set layout if needed*/); 
         //panel.add(new JButton("Hello")); //add components to panel

        getContentPane().add(panel);//why did you add your JFrame again???? so I guess you'd wanna add a JPanel or something with the components you need.

        pack();//this will override setsize and use LayoutManager
        setVisible(true);     
 }
...
}

但不建议扩展
JFrame

请发布简短的sscce或完整代码。最简单的解决方法是创建一个非静态方法来创建UI,并使用
newclass_name().method_name()对其进行初始化因此,因为您使用的是非静态方法,所以您可以访问非静态方法methods@DavidKroukamp我添加了完整的代码。我将尝试你的建议+1,因为我通常会将这些东西分开,然后扩展类,没有问题。除非重写组件方法,否则应该使用Swing组件,而不是扩展它们。组合重于继承。“不能从静态上下文引用非静态方法add(java.awt.Component)”,应该为CLI应用解决这些问题。我建议你回顾课程笔记,完成前面的任务和练习。如果我不扩展JFrame,我如何使用setLayout和setSize方法?@Caleb:没有必要在JFrame上调用
setLayout(…)
,因为它的内容窗格默认使用BorderLayout。另外,您希望避免对任何东西调用
setSize(…)
,而是让组件在JFrame上调用
pack()
时找到它们的首选大小。大卫的回答是1+。@HovercraftFullOfEels+1感谢你对我忘记的事情提出了更好的建议:)@DavidKroukamp:“始终通过getContentPane()添加到JFrames contentPane().add();/frame.setContentPane(…)”两者都可以做同样的事情:-)+1@caleb.breckon:这将是明智的,如果您再次阅读Java的基本教程。您不需要扩展类来使用它们的方法(您为此创建了对象),而是要更改它们的特性并向它们添加新的内容。只有带有受保护访问说明符的方法(不在同一个包中)才能在您描述的术语中使用。请仔细观察中任何人的回答,您可能会得到关于如何在不扩展类的情况下调用方法的答案。
public class CalebBreckonHW3  extends JFrame{

    public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
        new CalebBreckonHW3().createandShowUI();
       }

    });
 }
 private void createAndShowUI() {
        setTitle("Greeting App");
        //setSize(700,700); //not recommened
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

         JPanel panel=new JPanel(/*set layout if needed*/); 
         //panel.add(new JButton("Hello")); //add components to panel

        getContentPane().add(panel);//why did you add your JFrame again???? so I guess you'd wanna add a JPanel or something with the components you need.

        pack();//this will override setsize and use LayoutManager
        setVisible(true);     
 }
...
}