在JFrame的JPanel上添加画布。

问题描述 投票:0回答:1

首先,我还是个初学者,几个月前才开始学习java,直到几周前才开始使用图形组件。我的问题是这样的:我得到了一个JFrame作为容器,然后用Canvas "canvas "来存储BufferedImages,用JPanel "bPanel "来存放三个JButtons。出于某种原因,即使我使用bPanel.setOpaque(false)或者bPanel.setBackground(new Color(0,0,0,0),无论我先添加哪个,再添加哪个,无论我把Canvas添加到JFrame上还是JPanel上,JPanel仍然会挡住Canvas.我在网上找了几个小时,尝试了至少5种不同的解决方案,但都没有成功。出于某种原因,我无法通过JPanel加载图片,可能是因为我的display类没有扩展任何东西。无论如何,让我们继续:以下是我的代码(是的,我知道我可以使用Display扩展JFrame,但这不能解决这个问题,我已经试过了)。

public class Display {

private Game game;

private JFrame frame;
private Canvas canvas;
private JPanel bPanel;

private String title;
private int width, height;

private JButton stand, draw, reset;
private Icon drawIMG, standIMG, resetIMG;
private int bwidth, bheight;

public Display(String title, int width, int height) {

    this.title = title;
    this.width = width;
    this.height = height;

    createDisplay();

}

private void createDisplay() {

    frame = new JFrame(title);
    frame.setSize(width, height);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);

    canvas = new Canvas();
    canvas.setPreferredSize(new Dimension(width, height));
    canvas.setMaximumSize(new Dimension(width, height));
    canvas.setMinimumSize(new Dimension(width, height));
    canvas.setFocusable(false);

    bPanel = new JPanel();
    bPanel.setSize(width, height);
    bPanel.setPreferredSize(new Dimension(width, height));
    //bPanel.setOpaque(false);
    bPanel.setBackground(new Color(0, 0, 0, 0));
    bPanel.setLayout(null);

    drawIMG = new ImageIcon(this.getClass().getResource("/textures/button_draw.png"));
    standIMG = new ImageIcon(this.getClass().getResource("/textures/button_stand.png"));
    resetIMG = new ImageIcon(this.getClass().getResource("/textures/button_reset.png"));
    draw = new JButton(drawIMG);
    stand = new JButton(standIMG);
    reset = new JButton(resetIMG);
    draw.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent drawClicked) {
            if (game.getPhase() == 1)
                game.playerDraw();
        }
    });
    stand.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent standClicked) {
            if (game.getPhase() == 1)
            {
                game.setPhase(2);
                removeButtons();
            }
        }
    });
    reset.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent resetClicked) {
            game.reset();
        }
    });
    bwidth = 300;
    bheight = 100;
    //bPanel.add(new JLabel(new ImageIcon(getClass().getResource("/textures/background.png"))), BorderLayout.CENTER);
    addButton(draw);
    addButton(stand);
    addButton(reset);
    draw.setBounds(100, ((height/2)-(bheight/2)), bwidth, bheight);
    stand.setBounds(((width-100)-bwidth), ((height/2)-(bheight/2)), bwidth, bheight);
    reset.setBounds(((width/2)-40), (height-120), 80, 80);

    frame.add(canvas);
    frame.add(bPanel);
    frame.pack();

}

public void showImage(String path) {

    JLabel jl = new JLabel();
    jl.setIcon(new javax.swing.ImageIcon(getClass().getResource(path)));
    frame.add(jl);
    frame.repaint();

}

public void setGame(Game game) {
    this.game = game;
}

public void addButton(JButton button) {
    bPanel.add(button);
    bPanel.setLayout(null);
}

public void showButtons() {
    draw.setVisible(true);
    stand.setVisible(true);
}

public void removeButtons() {
    draw.setVisible(false);
    stand.setVisible(false);
}

public void removePanel(JPanel panel) {
    frame.remove(panel);
}

public Canvas getCanvas() {
    return canvas;
}

public JFrame getFrame() {
    return frame;
}

public JPanel getBPanel() {
    return bPanel;
}

}

例如,在我的这个尝试中,只有在JButton "stand "被按下后,图片才会显示。

public void showImage(String path) {

    JLabel jl = new JLabel();
    jl.setIcon(new javax.swing.ImageIcon(getClass().getResource(path)));
    frame.add(jl);
    frame.repaint();

}

我很绝望,因为我花了很多时间来寻找加载图形的解决方案。

java image swing canvas jpanel
1个回答
2
投票

几个问题。

  1. 不要使用空布局 Swing被设计为与布局管理器一起使用。
  2. 一个JFrame的默认布局管理器是BorderLayout。如果你不指定约束,组件会被添加到CENTER。CENTER中只能显示一个组件。所以你不能一直向框架中添加组件。你需要有一个父子层次结构。
  3. 不要使用Canvas。那是一个AWT组件。如果你想在Swing中进行自定义绘画,你可以使用JPanel

所以你的代码可能是这样的

//addButton(draw);
//addButton(stand);
//addButton(reset);
bPanel(draw);
bPanel(stand);
bPanel(reset);

JPanel的默认布局管理器是FlowLayout. 所以按钮将从左到右添加,并在面板上居中。

//frame.add(bPanel);
frame.add(bPanel, BorderLayout.PAGE_START);

现在所有的按钮将被添加到框架的顶部。

//private Canvas canvas;
private JPanel canvas;
….
//canvas = new Canvas();
canvas = new JPanel(new BorderLayout());
…
//frame.add(canvas);
frame.add(canvas, BorderLayout.CENTER);

现在 "画布 "将被添加到框架的BorderLayout的CENTER,这意味着它将占据所有按钮面板没有使用的空间。

public void showImage(String path) {

    JLabel jl = new JLabel();
    jl.setIcon(new javax.swing.ImageIcon(getClass().getResource(path)));
    frame.add(jl);
    frame.repaint();

}

你不能直接将图像添加到框架中,因为你已经将其他组件添加到框架中。相反,请使用。

    //frame.add(jl);
    //frame.repaint();
    canvas.add(jl);
    canvas.repaint();

这样图像就会被添加到画布上,而画布又会被添加到框架上,所以你有一个父子层次结构。

//draw.setBounds(100, ((height/2)-(bheight/2)), bwidth, bheight);
//stand.setBounds(((width-100)-bwidth), ((height/2)-(bheight/2)), bwidth, bheight);
//reset.setBounds(((width/2)-40), (height-120), 80, 80);

上面的代码是不需要的,因为布局管理器的工作是根据布局管理器的规则来设置每个组件的大小和位置。

所以基本上你需要重新开始,学习一些Swing的基础知识。也许你需要从头开始学习一些Swing的基础知识。 摇摆教程 会有帮助。这里有如何使用每个布局管理器的演示。

© www.soinside.com 2019 - 2024. All rights reserved.