javagui难倒了。JFrame中只有一个显示

javagui难倒了。JFrame中只有一个显示,java,swing,jframe,jpanel,paintcomponent,Java,Swing,Jframe,Jpanel,Paintcomponent,我正在尝试创建包含三个JPanel的Jframe。我扩展了JPanel,以便每次都可以传递颜色和直径。最终结果是一个JFrame,它有一个红色、一个黄色和一个绿色的stoplightpanel。我计划在这些面板中添加一个ActionListener,这就是为什么它是这样设计的。它不工作,因为目前,我只能看到黄色面板 这是给一个班级的警告。所以我尝试了我能想到的每一种配置,但我仍然只看到Jframe中存在的子类的一个实例。如果有人能指出明显的问题,我将不胜感激。奇怪的是,只有我的黄灯显示 impo

我正在尝试创建包含三个JPanel的Jframe。我扩展了JPanel,以便每次都可以传递颜色和直径。最终结果是一个JFrame,它有一个红色、一个黄色和一个绿色的stoplightpanel。我计划在这些面板中添加一个ActionListener,这就是为什么它是这样设计的。它不工作,因为目前,我只能看到黄色面板

这是给一个班级的警告。所以我尝试了我能想到的每一种配置,但我仍然只看到Jframe中存在的子类的一个实例。如果有人能指出明显的问题,我将不胜感激。奇怪的是,只有我的黄灯显示

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


class TrafficLight3 extends JFrame {

    public static void main ( String [] args ) {
        TrafficLight3 tl = new TrafficLight3 ( );
    }

    // Constructor 
    public TrafficLight3( ) {

        setTitle( "Traffic Light" );
        setSize ( 200, 400 );
        setLocation ( 200, 200 );
        setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );

        StopLightPanel red = new StopLightPanel( 100, Color.RED );

        // add stoplight panel's to JFrame's default border layout. 
        add( red, BorderLayout.NORTH );

        StopLightPanel yellow = new StopLightPanel( 100, Color.YELLOW );
        add( yellow, BorderLayout.CENTER );        

        StopLightPanel green = new StopLightPanel( 100, Color.GREEN );
        add ( green, BorderLayout.SOUTH );        

        setVisible( true );
    }
    class StopLightPanel extends JPanel {

        private int diameter;
        private Color color;

        public StopLightPanel ( int d, Color c) {

             diameter = d;
            color = c;
        }

        public void paintComponent ( Graphics g ) {

            g.setColor ( color );
            g.fillOval ( 50, 25, diameter, diameter );
       }
     }  
}
您需要覆盖自定义JPanel的getPreferredSize,以便布局管理器知道如何使它们变大。中心位置将调整面板的大小以使用所有可用空间,但其他位置不会。请参阅此示例,该示例还删除了setSize和setLocation,并将其替换为对pack的调用

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TrafficLight3 extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            TrafficLight3 tl = new TrafficLight3();

        }

    });
    }

    // Constructor
    public TrafficLight3() {

        setTitle("Traffic Light");
        // setSize(200, 400);
        // setLocation(200, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        StopLightPanel red = new StopLightPanel(100, Color.RED);

        // add stoplight panel's to JFrame's default border layout.
        add(red, BorderLayout.NORTH);

        StopLightPanel yellow = new StopLightPanel(100, Color.YELLOW);
        add(yellow, BorderLayout.CENTER);

        StopLightPanel green = new StopLightPanel(100, Color.GREEN);
        add(green, BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    class StopLightPanel extends JPanel {

        private int diameter;
        private Color color;

        public StopLightPanel(int d, Color c) {

            diameter = d;
            color = c;
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillOval(50, 25, diameter, diameter);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 133);
        }
    }
}
您需要覆盖自定义JPanel的getPreferredSize,以便布局管理器知道如何使它们变大。中心位置将调整面板的大小以使用所有可用空间,但其他位置不会。请参阅此示例,该示例还删除了setSize和setLocation,并将其替换为对pack的调用

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TrafficLight3 extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            TrafficLight3 tl = new TrafficLight3();

        }

    });
    }

    // Constructor
    public TrafficLight3() {

        setTitle("Traffic Light");
        // setSize(200, 400);
        // setLocation(200, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        StopLightPanel red = new StopLightPanel(100, Color.RED);

        // add stoplight panel's to JFrame's default border layout.
        add(red, BorderLayout.NORTH);

        StopLightPanel yellow = new StopLightPanel(100, Color.YELLOW);
        add(yellow, BorderLayout.CENTER);

        StopLightPanel green = new StopLightPanel(100, Color.GREEN);
        add(green, BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    class StopLightPanel extends JPanel {

        private int diameter;
        private Color color;

        public StopLightPanel(int d, Color c) {

            diameter = d;
            color = c;
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillOval(50, 25, diameter, diameter);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 133);
        }
    }
}

1-确保您的代码在

2-@Flight2039是正确的,似乎位置不是中心的BorderLayout使用preferredSize来确定大小。所以你可以覆盖getPreferredSize

3-当您覆盖油漆组件时。。你必须呼叫super.paintComponent。。遵循绘画方法链接。更多信息

4-始终添加@Override注释这将在编译时进行检查,例如,如果您在重写该方法时进行了一些键入操作

看到这个可运行的示例,我使用了一列三行的gridLayout

package test2;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TrafficLight3 {

    private JPanel redPanel;
    private JPanel yellowPanel;
    private JPanel greenPanel;

    // Constructor
    public TrafficLight3() {        
        redPanel = new StopLightPanel(100, Color.RED);
        yellowPanel = new StopLightPanel(100, Color.YELLOW);
        greenPanel = new StopLightPanel(100, Color.GREEN);
    }

    private static class StopLightPanel extends JPanel {
        private int diameter;
        private Color color;

        public StopLightPanel(int d, Color c) {
            diameter = d;
            color = c;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillOval(50, 25, diameter, diameter);
        }

        @Override
        public Dimension getPreferredSize(){
            int x = diameter*2;
            return new Dimension(x,x);
        }
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("Traffic Light");
        frame.setSize(200,500);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new GridLayout(3,1));
        frame.setLocationByPlatform(Boolean.TRUE);
        TrafficLight3 example = new TrafficLight3();
        frame.add(example.redPanel);
        frame.add(example.yellowPanel);
        frame.add(example.greenPanel);
        // Display the window.      
        frame.setVisible(Boolean.TRUE);
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

}
和输出


1-确保您的代码在

2-@Flight2039是正确的,似乎位置不是中心的BorderLayout使用preferredSize来确定大小。所以你可以覆盖getPreferredSize

3-当您覆盖油漆组件时。。你必须呼叫super.paintComponent。。遵循绘画方法链接。更多信息

4-始终添加@Override注释这将在编译时进行检查,例如,如果您在重写该方法时进行了一些键入操作

看到这个可运行的示例,我使用了一列三行的gridLayout

package test2;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TrafficLight3 {

    private JPanel redPanel;
    private JPanel yellowPanel;
    private JPanel greenPanel;

    // Constructor
    public TrafficLight3() {        
        redPanel = new StopLightPanel(100, Color.RED);
        yellowPanel = new StopLightPanel(100, Color.YELLOW);
        greenPanel = new StopLightPanel(100, Color.GREEN);
    }

    private static class StopLightPanel extends JPanel {
        private int diameter;
        private Color color;

        public StopLightPanel(int d, Color c) {
            diameter = d;
            color = c;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(color);
            g.fillOval(50, 25, diameter, diameter);
        }

        @Override
        public Dimension getPreferredSize(){
            int x = diameter*2;
            return new Dimension(x,x);
        }
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        // Create and set up the window.
        JFrame frame = new JFrame("Traffic Light");
        frame.setSize(200,500);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new GridLayout(3,1));
        frame.setLocationByPlatform(Boolean.TRUE);
        TrafficLight3 example = new TrafficLight3();
        frame.add(example.redPanel);
        frame.add(example.yellowPanel);
        frame.add(example.greenPanel);
        // Display the window.      
        frame.setVisible(Boolean.TRUE);
    }

    public static void main(String[] args) {
        // Schedule a job for the event-dispatching thread:
        // creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

}
和输出


请编辑您的问题,为我们提供更多信息?也就是说:1你想要完成的,2你不想完成的。当你这样做的时候,我会删除我的否决票。谢谢你,很抱歉给你带来任何困惑,我已经更新了它,但是如果不够清晰,请告诉我。我正在寻求帮助,所以我想让它尽可能简单。你能编辑你的问题,为我们提供更多信息吗?也就是说:1你想要完成的,2你不想完成的。当你这样做的时候,我会删除我的否决票。谢谢你,很抱歉给你带来任何困惑,我已经更新了它,但是如果不够清晰,请告诉我。我请求帮助,所以我想让它尽可能简单。谢谢你,这很有帮助。我正在努力设置首选的尺寸,这会带来不同。我看到边框布局具有首选的大小,因此有必要覆盖它。我不确定setLocationRelative null是否存在,但我可以用谷歌搜索它。我假设设置了此选项,以便在打开窗口时正确调整大小。无论如何,谢谢你给我的提示,我现在在正确的轨道上。setLocationRelativeTonull将窗口定位在屏幕中央。啊,我会经常使用它,然后谢谢你。当我能够升级投票时,我会向您发送一些。不要忘记添加对super.paintcomponent的所需调用,并确保代码使用EventQueue.invokeLater在EDT中运行。。然后你将赢得我的+1,SetLocationByPlatform谢谢你这非常有用。我正在努力设置首选的尺寸,这会带来不同。我看到边框布局具有首选的大小,因此有必要覆盖它。我不确定setLocationRelative null是否存在,但我可以用谷歌搜索它。我假设设置了此选项,以便在打开窗口时正确调整大小。无论如何,谢谢你给我的提示,我现在在正确的轨道上。setLocationRelativeTonull将窗口定位在屏幕中央。啊,我会经常使用它,然后谢谢你。当我能够升级投票时,我会向您发送一些。不要忘记添加对super.paintcomponent的所需调用,并确保代码使用EventQueue.invokeLater在EDT中运行。。然后你将赢得我的+1,SetLocationByPlatt。非常感谢你,你是对的,你和下面的海报都帮了大忙。我切换到网格布局并添加覆盖注释。我在后面也注意到了调用,并将在任何非类赋值中实现它。@user2557015很好
ELP,考虑接受绿色标志的答案。作为旁注,您的内部类应该是静态嵌套类,因为该类不属于顶级类的实例。非常感谢您,您是正确的,您和下面的海报都提供了很大的帮助。我切换到网格布局并添加覆盖注释。我稍后也注意到了这个调用,并将在任何非类的赋值中实现它。@ USER 2557015很好地帮助,考虑用绿色标记接受答案。另外,您的内部类应该是静态嵌套类,因为该类不属于顶级类的实例。