(初级)
嗨,对不起具体的问题,但是我有错误不断地用一个我希望非常简单的程序埋伏我。
我计划创建一个程序,允许用户在GridLayout中单击JPanels以更改其颜色。想象一个穷人的像素艺术节目,就像旧的MS Paint一样 计划是创建一个设置为GridLayout的JFrame,它具有整数宽度和高度,并使用带有2d数组和for循环的JPanels填充网格。然后我会将一个MouseListener放入每个单独的JPanel中以监听mouseClicked,这将改变所点击面板的背景颜色。
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,但显然它们必须是最终的或有效的最终。
答案 0 :(得分:2)
我重新安排了你的代码,将它们组合在一起。
这是我创建的GUI。
我对您的代码进行了以下更改。
我有主类实现Runnable。由于EventQueue invokeLater方法需要Runnable,因此您也可以将主类设为Runnable。
我将JPanel创建移动到了createPixels方法中。你的方法应该做一件事,做好一件事。
initGUI方法现在只创建JFrame。
我将大小整数移动到新的PixelPanel类中。扩展JPanel的类必须提供首选大小。然后,JFrame pack方法创建一个正确大小的JFrame。
在PixelPanel类的paintComponent方法中,我所做的只是绘画。除了在paintComponent方法中绘制外,您不应该做任何其他事情。
我将像素设置得更大,因此我可以更容易地点击并右键点击像素。左键单击使像素变为蓝色,右键单击则会删除蓝色(使像素变为白色)。
由于model / view / controller pattern,我将鼠标适配器代码拉入其自己的类中。分离关注点使得GUI的每个部分都能够更加轻松地工作。
这是代码。
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PixelPainter implements Runnable {
private JFrame frame;
public static void main(String[] args) {
EventQueue.invokeLater(new PixelPainter());
}
@Override
public void run() {
initGUI();
}
public void initGUI() {
frame = new JFrame("Pixel Art");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createPixels());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JPanel createPixels() {
int width = 30;
int height = 20;
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(height, width, 0, 0));
for (int row = 0; row < height; row++) {
for (int column = 0; column < width; column++) {
PixelPanel pixelPanel = new PixelPanel();
pixelPanel.addMouseListener(new ColorListener(pixelPanel));
panel.add(pixelPanel);
}
}
return panel;
}
public class PixelPanel extends JPanel {
private static final long serialVersionUID = 8465814529701152253L;
private static final int PIXEL_SIZE = 20;
private Color backgroundColor;
public PixelPanel() {
this.backgroundColor = Color.WHITE;
this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
this.setPreferredSize(new Dimension(PIXEL_SIZE, PIXEL_SIZE));
}
public Color getBackgroundColor() {
return backgroundColor;
}
public void setBackgroundColor(Color backgroundColor) {
this.backgroundColor = backgroundColor;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(getBackgroundColor());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
public class ColorListener extends MouseAdapter {
private PixelPanel panel;
public ColorListener(PixelPanel panel) {
this.panel = panel;
}
@Override
public void mousePressed(MouseEvent event) {
if (event.getButton() == MouseEvent.BUTTON1) {
panel.setBackgroundColor(Color.BLUE);
panel.repaint();
} else if (event.getButton() == MouseEvent.BUTTON3) {
panel.setBackgroundColor(Color.WHITE);
panel.repaint();
}
}
}
}
答案 1 :(得分:1)
您的代码正在循环中创建一个新的像素阵列。我的想法是在loo中创建Array out,然后创建一个新的JPanel以添加到循环内的Array。
类似的东西:
int[][] pixGrid = new int [width][height];
JPanel pixel[][] = new JPanel[width][height];
和
//JPanel pixel[][] = new JPanel[width][height];
pixel[row][col] = new JPanel();
现在在侦听器中,因为您将侦听器添加到每个面板,您可以直接访问该面板而无需担心鼠标点:
//JPanel selectedPixel = (JPanel) getComponentAt(click.getPoint());
JPanel selectedPixel = (JPanel)click.getSource();
实际上,您可以创建一个MouseListener来添加到每个面板,而不是为每个面板创建不同的侦听器,因为上面的代码是通用的。