Добавление панели из другого класса в основной класс - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь добавить JPanels и JButton из отдельного класса в кадр, который находится в основном классе. Программа компилируется без ошибок, но показывает только черное окно. Визуальная цель - иметь кнопку, которая меняет цвет при нажатии. Я создаю кнопку в классе GUI_1_1 и создаю фрейм в основном классе. Что я делаю неправильно?

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);

    }

}

Второй класс ниже

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;
            }
        }
    }
}

1 Ответ

1 голос
/ 17 октября 2019

Хорошо, здесь есть много чего объяснить, что вы делаете неправильно, поэтому я не смогу все это разобрать для вас. Хотя я могу начать с основ.

Во-первых

Не принимайте это слишком усердно. Свинг - это нечто свое. Java имеет репутацию очень абстрактного, поэтому вам не нужно знать, как она работает - just call it and let Java figure it out for you. Я не совсем согласен с этим для Java, но для Swing я абсолютно не согласен с этим. Именно по этой причине Swing получает плохую репутацию, и я думаю, что он неоправдан в 90% случаев.

То, что вы вызываете абстрактный API, не означает, что вам не нужно знать, как он работает. ,Качаться особенно так. Тем не менее, я даже не могу начать разбирать его в этом ответе, потому что есть много особенностей, многие из которых даже не относятся непосредственно к вашему коду, но вы должны знать косвенно, так что вам просто придется потратитьвремя на изучение, которое просто требует времени и чтения. Однако самое важное, что нужно убрать, это то, что Swing - это не просто абстрактный черный ящик, который вам не нужно понимать - вы должны изучать его, а не просто вызывать случайные функции, иначе вы обнаружите, что ваш код ведет себя неправильно, если вы это сделаете.

Во-вторых

И вы можете видеть это как раздражение (и не связанное с вашим вопросом), но это становится важным позже, когда вы закончите учиться - работайте над именами классов. Классы должны описывать то, что они делают, поэтому JavaDocs полезны, но они не должны быть на 100 процентов необходимыми для того, чтобы кто-то читал ваш код, чтобы понять, что он делает.

Третий

Инаконец-то добрались до вашего вопроса.

EDT

Никогда не работайте с GUI вне потока диспетчеризации событий (EDT). В любой среде с графическим интерфейсом у вас есть один отдельный поток, который выполняет эту работу. Он есть в вашем музыкальном проигрывателе, ваш интернет-браузер - Java ничем не отличается. И действительно, чтобы понять, как это важно - если вы можете понять, как выполнять работу с многопоточным графическим интерфейсом, вы заработаете много денег и никогда не будете работать еще один день до конца своей жизни.

ВашМетод main запускается в отдельном потоке, а EDT неявно запускается вашей программой. Ваш графический интерфейс должен быть обновлен в EDT, и те абстрактные вещи, которые Java (и Swing) делают, о которых я упоминал ранее, автоматически произойдут в EDT. Ваш код, однако, нет. То, на что вы хотите посмотреть, это 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

Тогда есть строка, где вы говорите:

frame.add(new GUI_1_1());

Так что JFrame немного отличается от других контейнеров. Вы не хотите «добавлять» вещи в JFrame. Вместо этого вы хотите установить JPanel в качестве панели содержимого вашей JFrame.

Кроме этого, строку, перед которой вы получите панель содержимого, а затем установить ее цвет фона. Теперь, когда вы будете использовать GUI_1_1 в качестве панели содержимого, вы можете представить, что эта строка больше не будет иметь смысла. Кстати, что касается вашего черного экрана, который вы утверждаете, что видите, ваша панель контента, не являющаяся вашим дисплеем, кажется проблемой.

LayoutManager

Одна из вещей, которые вы делаете в *Конструктор 1045 * должен установить менеджер макета на нуль. Это еще одна целая вещь, которая сама по себе, которую я не буду подробно описывать, потому что слишком много печатать - и Oracle уже проделала хорошую работу с этим, которую я полностью рекомендую прочитать, чтобы понять, как правильно использовать менеджеры компоновки: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html

И снова и снова

Я мог бы продолжать некоторое время, но этот ответ уже довольно многословен в его нынешнем виде. Как я уже говорил, Swing - это все, что ему нужно, и для этого нужно просто изучить его, как и для любого другого API.

Я могу продолжать редактировать этот ответ с дополнительной информацией или ссылками на дополнительные материалы, если у вас есть другие вопросы или другие особенности. Но я собираюсь сократить это, чтобы не выдвигать больше предложений «общего назначения», из тех, что я уже изложил выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...