简体   繁体   中英

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. The program compiles with no errors, but only shows a black 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. 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

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. 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 . I don't totally agree with that for Java, but for Swing I absolutely disagree with it. Swing gets a bad reputation for this very reason, and I think its unwarranted 90 percent of the time.

Just because you're calling an abstracted API doesn't mean you don't have to know how it works. Swing is especially this way. 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.

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. 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.

Third

And finally getting to your question.

EDT

Never do GUI work outside of the Event Dispatch Thread (EDT). In any environment that has a GUI, you have one singular thread to do that display work. Your music player has it, your internet browser deals with it - Java is no different. 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.

Your main method is run in a thread of it's own, and the EDT is started implicitly by your program. 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. 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

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

Then there's the line where you say:

frame.add(new GUI_1_1());

So a JFrame is a little different than other containers. You don't want to 'add' things to a JFrame . Instead, you want to set your JPanel as the content pane of your 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. 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. 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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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