首页 文章

JPanel中的绘画在错误的位置和大小上绘画

提问于
浏览
0

我正在开发一个Java GUI,我有一个600x800的JFrame,我想分成两部分,顶部有设置复选框,600 x 200,底部是“画布”,它将被绘制在那是600x600 . 我有一个JFrame,其中包含一个JPanel,其中包含两个其他JPanel(一个用于设置,另一个用于画布) . 我正在测试“绘画”,出于某种原因,当我尝试绘制一个600x600黑色矩形时,它会在JPanel设置所占区域中绘制一个小得多的矩形 . 有什么想法发生了什么?我正在使用repaint方法调用paintComponent,我尝试在我的JFrame的构造函数和要绘制的JPanel中调用repaint .

HPAProgram

public class HPAProgram {
    public static void main(String[] args) {
        MapWindow map = new MapWindow();        
    }
}

MapWindow

//import java.awt.*;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.*;

import javax.swing.*;  //notice javax
public class MapWindow extends JFrame
{
    private static final int WIDTH = 600, HEIGHT = 800;

    JPanel panel = new JPanel();
    SettingsButtonsPanel button_panel = new SettingsButtonsPanel();
    MapImagePanel map_panel = new MapImagePanel();
    public MapWindow()
    {

        setLocationRelativeTo(null);
        setTitle("HPA* Test");
        setSize(WIDTH, HEIGHT);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        add(panel);
        panel.setBounds(0, 0, 600, 800);
        //panel.setLayout(new GridBagLayout());
        /*GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;*/

        panel.add(button_panel);

        /*c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;*/

        panel.add(map_panel);

        button_panel.setLocation(0,0);
        /*map_panel.setLocation(0,200);
        map_panel.setSize(600,600);*/
        map_panel.repaint();

    }

}

SettingsButtonsPanel

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class SettingsButtonsPanel extends JPanel implements ItemListener{
    private static final int WIDTH = 600, HEIGHT = 200;
    private static final int NUM_MAP_TYPE = 2;

    private JCheckBox[] map_type;

    JPanel panel = new JPanel();

    public SettingsButtonsPanel(){

        this.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

        this.setBounds(0,0,WIDTH, HEIGHT);

        map_type = new JCheckBox[NUM_MAP_TYPE];

        map_type[0] = new JCheckBox("Sparse");
        map_type[0].setSelected(true);
        //map_type[0].setSize(100,100);


        map_type[1] = new JCheckBox("Maze");
        map_type[1].setSelected(false);
        //map_type[1].setSize(100,100);

        for(int i = 0; i < NUM_MAP_TYPE; i++)
        {
            map_type[i].addItemListener(this);
            c.fill = GridBagConstraints.HORIZONTAL;
            c.gridx = 0;
            c.gridy = i;
            this.add(map_type[i], c);
        }
    }

    public void itemStateChanged(ItemEvent e)
    {
        Object source = e.getItemSelectable();
        //if(source == )
    }
}

MapImagePanel

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class MapImagePanel extends JPanel{
    public MapImagePanel()
    {
        this.setBounds(0,200, 600,600);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.fillRect(0,0,600,600);
    }
}

1 回答

  • 2

    你似乎有很多误解......

    JPanel ,默认情况下使用 FlowLayout . FlowLayout 利用每个组件的首选大小来确定每个组件的大小 . 默认情况下,组件的首选大小为 0x0 .

    布局管理器还负责定位组件,因此使用 setBoundssetLocation 以及 setSize 会适得其反 .

    假设大小也不总是可能,特别是在处理文本时,因为这可以根据字体,显示驱动程序,渲染管道等的差异来改变大小......

    这就是Java制作大量布局管理器的原因 . 请查看Laying Out Components Within a Container了解更多详情

    Update with simple example

    不要混淆布局,使用具有不同布局的复合组件来实现您期望的结果,例如......

    SimpleLayout

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class SimpleLayout100 {
    
        public static void main(String[] args) {
            new SimpleLayout100();
        }
    
        public SimpleLayout100() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JPanel header = new JPanel();
                    header.add(new JLabel("Hello, I'm the header"));
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(header, BorderLayout.NORTH);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(600, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setColor(Color.GREEN);
                g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
                g2d.setColor(Color.RED);
                g2d.fillRect(150, 50, 300, 100);
                g2d.dispose();
            }
        }
    
    }
    

相关问题