【问题标题】:I have problems creating and showing the panel in the class MyPanel我在 MyPanel 类中创建和显示面板时遇到问题
【发布时间】:2021-08-12 15:02:46
【问题描述】:

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

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

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

【问题讨论】:

  • 看不到与 javafx 的任何关系?无论如何,坚持 java 命名约定,至少在公开显示代码时
  • 1) 您扩展了 JPanel 并在 MyPanel 中使用 JPanel。只需使用 JPanel。 2) JPanel 的paintComponent 方法用于使用Graphics 方法进行自定义绘画。您的代码可以使用普通方法,例如 createAndShowPanel。 3) 如果您按列、行顺序创建 Swing 组件,那么直观地调试您的 Swing 代码会容易得多。您在一个地方定义一个 JLabel 并将它添加到另一个地方的 JPanel。它在视觉上令人困惑。,

标签: java swing jframe jpanel


【解决方案1】:

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

该代码中存在许多逻辑错误,导致了许多问题。这是大多数带有 cmets 的更正代码。 (有些没有固定,因为它们最终没有太大的区别。)

根本问题来自扩展和创建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?](http://stackoverflow.com/q/7229226/418556)  
     * (Yes.)
     */
    /*
    public Dimension getPreferredSize() {
        return new Dimension(900,700);
    }
    */
}

【讨论】:

    【解决方案2】:

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

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

    我重新编写了您的 TemperaturePanel 类以创建并显示 JPanel。我按列、行顺序组织了您的 Swing 组件,因此我可以直观地验证 Swing 组件。我添加了缺少的JTextField。我创建了 getter 方法,因此您可以实际获取和设置 JTextFields 中的值。

    我格式化了代码并使用了正确的 camelCase 变量名。

    这是修改后的代码。我将TemperaturePanel 设为一个内部类,因此我可以将此代码作为一个块发布。

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

    【讨论】:

      猜你喜欢
      • 2012-10-16
      • 1970-01-01
      • 2020-01-31
      • 2012-02-23
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 2020-05-06
      • 1970-01-01
      相关资源
      最近更新 更多