简体   繁体   English

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

[英]Paint in JPanel is painting in the wrong location and size

I'm working on a Java GUI and I have a JFrame thats 600x800 that I want to split into two portions, the top which has checkboxes for settings and is 600 x 200 and the bottom which is the "canvas" which will be painted on that is 600x600. 我正在开发一个Java GUI,我有一个600x800的JFrame,我想分成两部分,顶部有设置复选框,600 x 200,底部是“画布”,它将被绘制在那是600x600。 I have a JFrame that has a JPanel that contains two other JPanels (one for the settings, the other for the canvas). 我有一个JFrame,其中包含一个JPanel,其中包含两个其他JPanel(一个用于设置,另一个用于画布)。 I'm testing the "painting" and for some reason when I try to paint a 600x600 black rectangle, it paints a much smaller rectangle in the area that the settings JPanel occupies. 我正在测试“绘画”,出于某种原因,当我尝试绘制一个600x600的黑色矩形时,它会在JPanel设置的区域中绘制一个小得多的矩形。 Any ideas what's going on? 有什么想法发生了什么? I'm using the repaint method to call paintComponent and I've tried calling repaint in both the constructor of my JFrame and in the JPanel that is to be painted. 我正在使用repaint方法调用paintComponent,我尝试在我的JFrame的构造函数和要绘制的JPanel中调用repaint。

HPAProgram HPAProgram

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

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

The are a number of misconceptions you seem to have... 你似乎有很多误解......

JPanel , by default uses a FlowLayout . JPanel默认使用FlowLayout FlowLayout makes use of each of the components preferred size to determine the size of each component. FlowLayout利用每个组件的首选大小来确定每个组件的大小。 By default, a component has a preferred size of 0x0 . 默认情况下,组件的首选大小为0x0

The layout manager is also responsible for positing the components, so using setBounds and setLocation and setSize is counter productive. 布局管理器还负责定位组件,因此使用setBoundssetLocation以及setSize会适得其反。

Assuming the size is also not always possible, especially when dealing with text, as this can change size based on differences in the fonts, display drivers, rendering pipelines etc... 假设大小也不总是可能,特别是在处理文本时,因为这可以根据字体,显示驱动程序,渲染管道等的差异来改变大小......

This is why Java makes extensive layout managers. 这就是Java制作大量布局管理器的原因。 Take a look at Laying Out Components Within a Container for more details 有关更多详细信息,请查看在容器布置组件

Update with simple example 用简单的例子更新

Don't be afaird to mix layouts, using compound components with different layouts, to achieve your desired results, for 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();
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM