代码之家  ›  专栏  ›  技术社区  ›  yapkm01

Java Swing:对JComponent/JPanel的基本理解

  •  0
  • yapkm01  · 技术社区  · 11 年前

    我有以下代码:

    public class OpaqueExample {
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                OpaqueFrame frame = new OpaqueFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
    
    }
    
    class OpaqueFrame extends JFrame {
    
    private static final long serialVersionUID = 5486007826709615846L;
    
    public OpaqueFrame() {
        super("Opacity Demo");
        this.setSize(200, 200);
        JComponent boxPanel = new BoxComponent(50, 50);
        this.add(boxPanel);
    }
    
    }
    
    class BoxComponent extends JComponent {
    
    private static final long serialVersionUID = -1935449999922455838L;
    
    public BoxComponent(int x, int y) {
        super();
        this.setSize(x, y);
        this.setLocation(40, 40);
    }
    
    public void paintComponent(Graphics g) {
        g.setColor(Color.red);
    }
    
    } 
    

    简单地说:
    a.创建了一个尺寸为200、200的框架
    b.创建了一个尺寸为50、50的长方体组件
    c.从框架的左上角开始设置箱形部件40、40的位置。盒子是红色的

    当我运行它时,我希望在框架容器中看到一个较小的红色框。我做对了吗?或者我只是不理解摆动组件的基本原理(似乎是这样)。

    请帮忙。 感谢

    2 回复  |  直到 11 年前
        1
  •  2
  •   MadProgrammer    11 年前

    没有足够的上下文来提供完整的答案。

    这只是你问题的另一个可能的解决方案。。。。

    如果您的意图是尝试将组件放置在特定位置,那么为什么不直接设置其背景颜色,而不是尝试使用自定义绘制来填充它呢?

    如果你打算画很多小方块,那么你不需要为每个小方块单独画一个组件。。。

    Swing旨在利用布局管理器API,它是框架工作的核心。

    虽然我会第一个承认 null 布局很有用,我会先(亲自)尝试很多东西。

    以下示例使用单个组件,但允许您在不同的位置和大小绘制多个框。。。

    enter image description here

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class GraphicsExample {
    
        public static void main(String[] args) {
            new GraphicsExample();
        }
    
        public GraphicsExample() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    TestPane tp = new TestPane();
                    tp.add(50, 50, 40, 40);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(tp);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
    
            });
        }
    
        public class TestPane extends JPanel {
    
            private List<Rectangle> boxes;
    
            public TestPane() {
                boxes = new ArrayList<Rectangle>(25);
            }
    
            public void add(int x, int y, int width, int height) {
                boxes.add(new Rectangle(x, y, width, height));
                repaint();
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.RED);
                for (Rectangle box : boxes) {
                    g2d.fill(box);
                }
                g2d.dispose();
            }        
        }    
    }
    

    你做错的另一件事就是不尊重油漆链。当您覆盖 paint 方法,必须调用 super.paintXxx 以确保油漆链不会断裂。这种方法做了很多重要的工作,如果你忘记把它们包括在内,那是非常不可原谅的;)

    退房 Performing Custom Painting 了解更多详细信息

        2
  •  1
  •   Cruncher    11 年前
    frame.setLayout(null);
    

    setLayout(null); 在框架的构造函数中

    这允许您直接定义零部件的位置

    public void paintComponent(Graphics g) {
        g.setColor(Color.red);
    }
    

    应将其更改为

    public void paintComponent(Graphics g) {
        g.setColor(Color.red);
        g.fillRect(0, 0, getWidth(), getHeight());
    }
    

    有关图形类的信息: http://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html