swing Java使用GridLayout和鼠标交互式JPanel创建JFrame
(初学者)
您好,很抱歉问您一个具体的问题,但我一直在用一个我认为非常简单的程序,不知从哪里冒出错误来埋伏我
我计划创建一个程序,允许用户在GridLayout中单击JPanel,以更改其颜色。想象一下一个穷人的像素艺术程序,比如旧的MS画作
计划是将JFrame设置为GridLayout,宽度和高度均为整数,并用一个2d数组和一个for循环填充网格。然后,我会在每个单独的JPanel中放一个鼠标听筒,听是否有鼠标点击,这会改变点击面板的背景颜色
package pixelpainter;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class PixelPainter extends JPanel {
int width = 20;
int height = 20;
int pixSize = 10;
Color bGColor = Color.WHITE;
Dimension pixDim = new Dimension(pixSize,pixSize);
private JPanel panelClicked = null;
JFrame frame= new JFrame();
/**
* @param args the command line arguments
*/
public PixelPainter()
{
initGUI();
}
public void initGUI() {
frame.setLayout(new GridLayout(height, width, 0, 0));
frame.setSize((height * pixSize), (width * pixSize));
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
int[][] pixGrid = new int [width][height];
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
JPanel pixel[][] = new JPanel[width][height];
frame.add(pixel[row][col]);
pixel[row][col].setBackground(bGColor);
pixel[row][col].setPreferredSize(pixDim);
pixel[row][col].setBorder(BorderFactory.createLineBorder(Color.BLACK));
pixel[row][col].addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent click)
{
JPanel selectedPixel = (JPanel) getComponentAt(click.getPoint());
if (selectedPixel == null || selectedPixel == PixelPainter.this)
{
return;
}
if (selectedPixel != null)
{
selectedPixel.setBackground(Color.BLACK);
}
}
@Override
public void mousePressed(MouseEvent press)
{
}
});
}
}
}
public static void main(String[] args){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
new PixelPainter().setVisible(true);
}
});
}
}
理想情况下,我会在填充颜色时使用2d数组JFrame,但显然它们必须是最终的或有效的最终
# 1 楼答案
我重新整理了你的代码,把类似的东西组合在一起
这是我创建的GUI
我对你的代码做了以下更改
我让主类实现可以运行。由于EventQueue invokeLater方法需要一个可运行的类,因此您不妨将主类设置为可运行的
我将JPanel创建移到createPixels方法中。你的方法应该做一件事,并且把这件事做好
initGUI方法现在只创建JFrame
我将大小整数移动到新的PixelPanel类中。扩展JPanel的类必须提供首选大小。然后,JFrame pack方法创建正确大小的JFrame
在PixelPanel类的paintComponent方法中,我所做的就是绘制。除了使用paintComponent方法进行绘制外,不应执行其他任何操作
我把像素变大了,这样我可以左键点击和右键点击一个像素更容易。左键单击会使像素变为蓝色,右键单击会擦除蓝色(使像素变为白色)
由于model / view / controller pattern,我将鼠标适配器代码拉入了它自己的类中。分离关注点可以使GUI的每个部分正常工作变得更容易
这是代码
# 2 楼答案
您的代码正在循环中创建一个新的像素阵列。这个想法是在loo外面创建一个数组,然后创建一个新的JPanel添加到循环内部的数组中
比如:
及
现在在监听器内部,因为您将监听器添加到每个面板中,您可以直接访问面板,而无需担心鼠标点:
实际上,您可以创建一个MouseListener来添加到每个面板,而不是为每个面板创建不同的侦听器,因为上面的代码是通用的