简体   繁体   English

将面板从另一个 Class 添加到主 Class

[英]Adding Panel from Another Class to Main Class

I am trying to add JPanels and JButtons from a separate class to the frame, which is in the main class.我正在尝试将单独的 class 中的 JPanel 和 JButton 添加到框架中,该框架位于主 class 中。 The program compiles with no errors, but only shows a black window.程序编译没有错误,但只显示黑色 window。 The visual goal is to have a button that changes color when clicked.视觉目标是让按钮在单击时改变颜色。 I create the button in the GUI_1_1 class, and create the frame in the main class.我在 GUI_1_1 class 中创建按钮,并在主 class 中创建框架。 What am I doing wrong?我究竟做错了什么?

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class main {
     public static void main(String[] args) {
        JFrame frame = new JFrame ("Cube GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setSize(1370,790);

        frame.getContentPane().setBackground(Color.BLACK);
        frame.add(new GUI_1_1());

        frame.setVisible(true);

    }

}

The second class is below下面是第二个 class

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class GUI_1_1 extends JPanel {
    private int count;
    private JButton button0;
    private JPanel mainpanel;
    private JPanel panel1;

    public GUI_1_1() {
        mainpanel = new JPanel();
        mainpanel.setLayout(null);


        count = 0;
        button0 = new JButton("[1][1]");
        button0.addActionListener(new ButtonListener());
        button0.setOpaque(true);
        button0.setBounds(60,310,50,50);

        mainpanel.add(button0);
        add(mainpanel);

    }

private class ButtonListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent event) {
            if(count==0){
                button0.setBackground(Color.RED);
                count = count + 1;
            } else if(count==1) {
                button0.setBackground(Color.GREEN);
                count = count + 1;
            } else if(count==2) {
                button0.setBackground(Color.ORANGE);
                count = count + 1;
            } else if(count==3) {
                button0.setBackground(Color.BLUE);
                count = count + 1;
            } else if(count==4) {
                button0.setBackground(Color.YELLOW);
                count = count + 1;
            } else if(count==5) {
                button0.setBackground(Color.WHITE);
                count = count - 5;
            }
        }
    }
}

OK, there's a lot to explain here of what you're doing wrong, so I won't be able to break it all down for you.好的,这里有很多东西要解释你做错了什么,所以我无法为你分解它。 I can start with the basics though.不过,我可以从基础开始。

Firstly首先

Don't take it too hard.不要太用力。 Swing is a thing of it's own. Swing 是它自己的东西。 Java has a reputation of being very abstract so you don't have to know how it works - just call it and let Java figure it out for you . Java 以非常抽象而著称,因此您不必知道它是如何工作的 - just call it and let Java figure it out for you I don't totally agree with that for Java, but for Swing I absolutely disagree with it.对于 Java,我并不完全同意,但对于 Swing,我绝对不同意。 Swing gets a bad reputation for this very reason, and I think its unwarranted 90 percent of the time. Swing 正是因为这个原因而声名狼藉,我认为 90% 的时间都是没有根据的。

Just because you're calling an abstracted API doesn't mean you don't have to know how it works.仅仅因为你调用一个抽象的 API 并不意味着你不必知道它是如何工作的。 Swing is especially this way. Swing 尤其是这种方式。 That said, I can't even begin to break it down in this answer because there are lots of specifics, a lot of which don't even apply directly to your code but you should know indirectly, so you'll just have to spend time learning it which just takes time and reading.也就是说,我什至无法在这个答案中开始分解它,因为有很多细节,其中很多甚至不直接适用于你的代码,但你应该间接知道,所以你只需要花费时间学习它只需要时间和阅读。 The most important thing to take away though, is that Swing is not just some abstract black box you don't have to understand - you must learn it and not just call random functions, or you will end up finding your code misbehaves if you do.不过,最重要的是,Swing 不仅仅是一些你不必理解的抽象黑盒——你必须学习它,而不仅仅是调用随机函数,否则你最终会发现你的代码行为不端.

Secondly第二

And you might see this a peeve (and not related to your question), but it becomes important later after you're done learning - work on your class naming.你可能会觉得这很烦人(与你的问题无关),但在你完成学习后它变得很重要 - 处理你的 class 命名。 Classes should be self-descriptive of what they do, so while JavaDocs are helpful, they shouldn't be 100 percent necessary for someone reading your code to understand what it's doing.类应该对它们所做的事情进行自我描述,因此尽管 JavaDocs 很有帮助,但对于阅读您的代码的人来说,它们不应该是 100% 必要的,以了解它在做什么。

Third第三

And finally getting to your question.最后回答你的问题。

EDT美东时间

Never do GUI work outside of the Event Dispatch Thread (EDT).切勿在事件调度线程 (EDT) 之外进行 GUI 工作。 In any environment that has a GUI, you have one singular thread to do that display work.在任何具有 GUI 的环境中,您都有一个单独的线程来完成该显示工作。 Your music player has it, your internet browser deals with it - Java is no different.您的音乐播放器拥有它,您的互联网浏览器可以处理它 - Java 也不例外。 And to really drive it home how important this is - if you can figure out how to do multithreaded GUI work, you stand to make a lot of money and never work another day for the rest of your life.并且要真正把它带回家,这是多么重要 - 如果您能弄清楚如何进行多线程 GUI 工作,那么您就可以赚很多钱,并且再也不会为您一生中的 rest 工作。

Your main method is run in a thread of it's own, and the EDT is started implicitly by your program.您的 main 方法在它自己的线程中运行,并且 EDT 由您的程序隐式启动。 Your GUI is supposed to be updated in the EDT, and those abstracted things that Java (and Swing) do that I mentioned early, will automatically happen in the EDT.您的 GUI 应该在 EDT 中更新,而我之前提到的 Java(和 Swing)所做的那些抽象的事情,将在 EDT 中自动发生。 Your code, however, does not.但是,您的代码没有。 What you want to look at are SwingUtilities.html#invokeLater(java.lang.Runnable) (or alternatively invokeAndWait(...) ) where you put your code as你想看的是SwingUtilities.html#invokeLater(java.lang.Runnable) (或者invokeAndWait(...) )你把你的代码作为

public static void main (String [] args) {
    SwingUtilities.invokeLater(()->{
        //things you want to happen only in the EDT
    });
    //other things to happen in your main thread

JFrame JFrame

Then there's the line where you say:然后就是你说的那一行:

frame.add(new GUI_1_1());

So a JFrame is a little different than other containers.所以JFrame与其他容器略有不同。 You don't want to 'add' things to a JFrame .您不想将东西“添加”到JFrame Instead, you want to set your JPanel as the content pane of your JFrame .相反,您希望将JPanel设置为JFrame的内容窗格。

Other than that, the line before that you get the content pane, and then set the background color of it.除此之外,您获取内容窗格之前的行,然后设置它的背景颜色。 Which, now that you'll be using your GUI_1_1 as the content pane, you can imagine how that line won't make sense anymore.其中,现在您将使用GUI_1_1作为内容窗格,您可以想象该行将不再有意义。 BTW, with relation to your black screen you claim to be seeing, your content pane not being your display seems to be the issue.顺便说一句,就您声称看到的黑屏而言,您的内容窗格不是您的显示器似乎是问题所在。

LayoutManager布局管理器

One of the things you're doing in GUI_1_1 's constructor is to set the layout manager to null.您在GUI_1_1的构造函数中所做的一件事是将布局管理器设置为 null。 This is another whole thing all it's own, which I won't really detail because it's too much to type - and Oracle has already done a nice job with that, which I fully recommend reading to figure out how to use layout managers correctly: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html这是它自己的另一件事,我不会真正详细说明,因为它的类型太多 - 而 Oracle 已经做得很好,我完全建议阅读以了解如何正确使用布局管理器: https ://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

And on and on不断地

I could keep going for a while on this but this answer is already pretty verbose as it stands.我可以继续讨论一段时间,但这个答案已经很冗长了。 Like I mentioned, Swing is a whole thing all it's own that requires just learning it, as with any API really.就像我提到的,Swing 是一个完整的东西,只需要学习它,就像任何 API 一样。

I can keep editing this answer with more information, or links to more reading if you have other questions or other specifics.如果您有其他问题或其他细节,我可以继续编辑此答案并提供更多信息或指向更多阅读的链接。 But I'm going to cut this short to keep more 'general purpose' suggestions out, from the ones I already put above.但我将缩短这一点,以保留更多“通用”建议,这些建议来自我上面已经提出的建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM