首先,我还是个初学者,几个月前才开始学习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();
}
我很绝望,因为我花了很多时间来寻找加载图形的解决方案。
几个问题。
所以你的代码可能是这样的
//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的基础知识。 摇摆教程 会有帮助。这里有如何使用每个布局管理器的演示。