我在 class MyPanel 中创建和显示面板时遇到问题

I have problems creating and showing the panel in the class MyPanel

我正在使用 Java Swing 开发一个 Uni 项目。我想创建一个包含温度和其他变量的统计面板。

我在 class MyPanel 中创建和显示面板时遇到问题。 当我将 Class Main 中的 MyPanel p = new MyPanel() 替换为 Class MyPanel 中方法 paintComponent 的内容时,它可以工作,但反之则不行。我想在单独的 class 中创建面板,然后调用它。

public class Main extends JFrame {
  
public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            JPanel p = createAndShowGUI();
        }
    });
}

    private static JPanel createAndShowGUI() {
        System.out.println("Created GUI on EDT? "+
        SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Swing Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       
        MyPanel p = new MyPanel(); 

        f.add(p);
        //f.add(new MyPanel());
        f.pack();
        f.setVisible(true);
        return p;
    } 
}
public class MyPanel extends JPanel {

    private JLabel TemperaturLabel ;
    private JTextField Temperatur ;
    private JLabel LuftfeuchtigkeitLabel;
    private JTextField Luftfeuchtigkeit;
    private JLabel luftdruckLabel;
    private JTextField luftdruck;
    private JLabel VorhersageLabel; 
    private JPanel Panel;

    protected void paintComponent(Graphics g) {
        TemperaturLabel = new JLabel("Temperatur: ");
        Temperatur = new JTextField(2);

        LuftfeuchtigkeitLabel  = new JLabel("Luftfeuchtigkeit: ");
        Luftfeuchtigkeit  = new JTextField(3);

        luftdruckLabel = new JLabel("Luftdruck: ");
        luftdruck = new JTextField(4);

        Panel= new JPanel( new GridBagLayout());

        VorhersageLabel = new JLabel("Vorhersage:------"); 

        GridBagConstraints c = new GridBagConstraints();
        c.insets= new Insets(10,10,10,10);

        c.gridx=0;
        c.gridy=1;
        Panel.add(TemperaturLabel,c);
        c.gridx=1;
        c.gridy=1;
        Panel.add(Temperatur,c);
        c.gridx=0;
        c.gridy=2;
        Panel.add(LuftfeuchtigkeitLabel,c);
        c.gridx=1;
        c.gridy=2;
        Panel.add(Luftfeuchtigkeit,c);
        c.gridx=0;
        c.gridy=3;
        Panel.add(luftdruckLabel,c);
        c.gridx=1;
        c.gridy=3;
        Panel.add(luftdruck,c);
        c.gridx=0;
        c.gridy=4;
        Panel.add(VorhersageLabel,c);
        c.gridx=1;
        c.gridy=4;
    } 

    public Dimension getPreferredSize() {
        return new Dimension(900,700);
    }
}

所以你期待看到这样的东西?

该代码中存在许多逻辑错误,导致了一系列问题。这是更正后的代码,其中大部分都带有注释。 (有些没修好,因为到最后也没什么大不了。)

根本问题来自扩展和创建 JPanel 的实例。最终出现在框架中的是未添加任何内容的扩展面板!

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

// Use meaningful names for classes, attributes and methods!
// Don't. Extend. JFrame! 
// public class Main extends JFrame {
public class MyPanelDisplayProblem {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // See comments below
                // JPanel p = createAndShowGUI();
                createAndShowGUI();
            }
        });
    }

    // why is this method returning anything? It makes no sense to do that.
    // private static JPanel createAndShowGUI() {
    private static void createAndShowGUI() {
        System.out.println("Created GUI on EDT? "
                + SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Swing Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Oh my! This clashes with another name in my 'junk code' package!
        // Again. Descriptive names!
        // MyPanel p = new MyPanel();
        WeatherPanel p = new WeatherPanel();

        f.add(p.getPanel());
        //f.add(new MyPanel());
        f.pack();
        f.setVisible(true);
    }
}

/* Don't extend panels either, unless custom painting. */
//class WeatherPanel extends JPanel {
class WeatherPanel {    

    /*
     *  Please learn common Java nomenclature (naming conventions - e.g. 
    `EachWordUpperCaseClass`, `firstWordLowerCaseMethod()`, 
    `firstWordLowerCaseAttribute` unless it is an `UPPER_CASE_CONSTANT`) 
    and use it consistently.
     */
    private JLabel TemperaturLabel ;
    private JTextField Temperatur ;
    private JLabel LuftfeuchtigkeitLabel;
    private JTextField Luftfeuchtigkeit;
    private JLabel luftdruckLabel;
    private JTextField luftdruck;
    private JLabel VorhersageLabel; 
    private JPanel Panel;

    /*
    The resoning here is entirely wrong. Components should be created and 
    added from within a constructor!
    */
    // protected void paintComponent(Graphics g) {
    public WeatherPanel() {
        TemperaturLabel = new JLabel("Temperatur: ");
        Temperatur = new JTextField(2);

        LuftfeuchtigkeitLabel  = new JLabel("Luftfeuchtigkeit: ");
        Luftfeuchtigkeit  = new JTextField(3);

        luftdruckLabel = new JLabel("Luftdruck: ");
        luftdruck = new JTextField(4);

        Panel= new JPanel( new GridBagLayout());

        VorhersageLabel = new JLabel("Vorhersage:------"); 

        GridBagConstraints c = new GridBagConstraints();
        c.insets= new Insets(10,10,10,10);

        c.gridx=0;
        c.gridy=1;
        Panel.add(TemperaturLabel,c);
        c.gridx=1;
        c.gridy=1;
        Panel.add(Temperatur,c);
        c.gridx=0;
        c.gridy=2;
        Panel.add(LuftfeuchtigkeitLabel,c);
        c.gridx=1;
        c.gridy=2;
        Panel.add(Luftfeuchtigkeit,c);
        c.gridx=0;
        c.gridy=3;
        Panel.add(luftdruckLabel,c);
        c.gridx=1;
        c.gridy=3;
        Panel.add(luftdruck,c);
        c.gridx=0;
        c.gridy=4;
        Panel.add(VorhersageLabel,c);
        c.gridx=1;
        c.gridy=4;
    } 
    
    // Now to get the panel that is created, we can add a 'get panel' method. 
    public JPanel getPanel() {
        return Panel;
    }

    /**
     * This is both unnecessary and counterproductive. 
     * See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size 
     * methods in Java Swing?](  
     * (Yes.)
     */
    /*
    public Dimension getPreferredSize() {
        return new Dimension(900,700);
    }
    */
}

我拿了你的代码,重新排列它,并添加了一些东西来获得这个 GUI。

我重新编写了您的 createAndShowGUI 方法以删除静态并使用我创建的新 getPanel 方法。

我重做了你的 TemperaturePanel class 以创建并显示 JPanel。我按列、行顺序组织了您的 Swing 组件,以便我可以直观地验证 Swing 组件。我添加了缺失的 JTextField。我创建了 getter 方法,因此您实际上可以在 JTextFields.

中获取和设置值

我格式化了代码并使用了正确的驼峰命名法变量名。

这是修改后的代码。我将 TemperaturePanel 设为内部 class 这样我就可以 post 将这段代码作为一个块。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TemperatureGUI {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TemperatureGUI().createAndShowGUI();
            }
        });
    }
    
    private void createAndShowGUI() {
        System.out.println("Created GUI on EDT? " + 
                SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Swing Demo");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        TemperaturePanel p = new TemperaturePanel();
        f.add(p.getPanel());
        // f.add(new MyPanel());
        f.pack();
        f.setLocationByPlatform(true);
        f.setVisible(true);
    }
    
    public class TemperaturePanel {

        private JTextField temperatur;
        private JTextField luftfeuchtigkeit;
        private JTextField luftdruck;
        private JTextField vorhersage;

        private JPanel panel;
        
        public TemperaturePanel() {
            this.panel = createAndShowPanel();
        }
        
        private JPanel createAndShowPanel() {
            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

            GridBagConstraints c = new GridBagConstraints();
            c.anchor =  GridBagConstraints.LINE_START;
            c.fill = GridBagConstraints.HORIZONTAL;
            c.weightx = 1.0;
            c.insets = new Insets(10, 10, 10, 10);

            c.gridx = 0;
            c.gridy = 1;
            JLabel temperaturLabel = new JLabel("Temperatur: ");
            panel.add(temperaturLabel, c);

            c.gridx = 1;
            c.gridy = 1;
            temperatur = new JTextField(10);
            panel.add(temperatur, c);

            c.gridx = 0;
            c.gridy = 2;
            JLabel luftfeuchtigkeitLabel = new JLabel("Luftfeuchtigkeit: ");
            panel.add(luftfeuchtigkeitLabel, c);

            c.gridx = 1;
            c.gridy = 2;
            luftfeuchtigkeit = new JTextField(10);
            panel.add(luftfeuchtigkeit, c);

            c.gridx = 0;
            c.gridy = 3;
            JLabel luftdruckLabel = new JLabel("Luftdruck: ");
            panel.add(luftdruckLabel, c);

            c.gridx = 1;
            c.gridy = 3;
            luftdruck = new JTextField(10);
            panel.add(luftdruck, c);

            c.gridx = 0;
            c.gridy = 4;
            JLabel vorhersageLabel = new JLabel("Vorhersage:------");
            panel.add(vorhersageLabel, c);

            c.gridx = 1;
            c.gridy = 4;
            vorhersage = new JTextField(10);
            panel.add(vorhersage, c);

            return panel;
        }

        public JTextField getTemperatur() {
            return temperatur;
        }

        public JTextField getLuftfeuchtigkeit() {
            return luftfeuchtigkeit;
        }

        public JTextField getLuftdruck() {
            return luftdruck;
        }

        public JTextField getVorhersage() {
            return vorhersage;
        }

        public JPanel getPanel() {
            return panel;
        }
        
    }

}