我正在尝试创建一个地图编辑器,我希望能够获得我使用Graphics2d绘制的网格位置。但是,我没有找到任何解决方案,因此我提出了在每个矩形内部使用MouseListener绘制隐形JLabel的想法。但是,我无法使JLabel适合绘制的矩形。
我这样做是因为我有多个要绘制的组件,我希望它们相互堆叠。因此,我不能使用任何组件,因为它们一次只能容纳1个图像。
这是目前使用的最低工作示例:
public class MainGui extends JFrame {
public MainGui(int width, int height) {
this.setTitle("Map Editor");
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
GuiGridPanel guiGridPanel = new GuiGridPanel(width, height);
add(guiGridPanel.buildGuiGrid(), BorderLayout.CENTER);
setSize(new Dimension(780,480));
setLocationRelativeTo(null);
setVisible(true);
}
}
public class GuiGridPanel extends JPanel {
private Graphics2D render;
private int width;
private int height;
private JPanel gridPanel;
private final int gridSize = 32;
public GuiGridPanel(int width, int height){
this.width = (width);
this.height = (height);
gridPanel = new JPanel(new GridLayout(height, width));
buildLabels();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
render = (Graphics2D) g;
drawMap();
}
public JScrollPane buildGuiGrid() {
add(gridPanel);
JScrollPane jScrollPane = new JScrollPane(this);
jScrollPane.getVerticalScrollBar().setUnitIncrement(16);
return jScrollPane;
}
private void buildLabels() {
for(int x = 0; x < height; x++) {
for (int y = 0; y < width; y++) {
JLabel label = new JLabel("HERE");
label.setBounds(x*gridSize, y*gridSize, gridSize, gridSize);
gridPanel.add(label);
}
}
}
private void drawMap() {
for(int x = 0; x < height; x++) {
for(int y = 0; y < width; y++) {
render.drawRect(x*gridSize, y*gridSize, gridSize, gridSize);
}
}
}
}
用于测试目的。我把&#34;在这里&#34;作为JLabels的名称,以确保它们进入每个矩形。但目前他们并没有这样做。我尝试修改JLabel的边界,甚至将其布局管理器设置为null,这样我就可以自由放置它们了,但是我无法让它工作。
由于
答案 0 :(得分:3)
不能解决你的问题,但变量&#34;渲染&#34;变量不应该被定义为实例变量。
Graphics对象只能在paintComponent()方法或paintComponent(...)方法调用的方法中使用。
因此应该在本地定义变量:
//render = (Graphics2D) g;
//drawMap();
Graphics2D render = (Graphics2D) g;
drawMap(render);
然后你改变了drawMap(...)方法:
//private void drawMap()
private void drawMap(Graphics2d render)
编辑:
我希望他们叠加在一起。因此,我不能使用任何组件,因为它们一次只能容纳1个图像。
您可以将组件添加到另一个组件:
JLabel background = new JLabel(...);
background.setLayout( new BorderLayout() );
JLabel foreground = new Jlabel(...);
background.add( foreground );
然后,您可以重复上面的内容并将另一个组件添加到&#34;前景&#34;。
另一种选择是创建一个包含多个图标的图标。查看Compound Icon以获取此方法的示例。
另一种方法可能是创建一个BufferedImage并在BufferedImage上将所有图像绘制在一起。
你的问题真的不清楚。我不知道这些图像是动态更改还是修复,所以很难建议一种方法。
答案 1 :(得分:1)
在下面的示例中,GridPainter
呈现指定大小的网格,其中每个单元格根据选择状态以蓝色填充(请参阅addMouseListener
)。
public class MainFrame extends JFrame {
public MainFrame() {
GridPainter gp = new GridPainter(5,5);
gp.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
// onLeftButtonClick
gp.selectCell(e.getX(), e.getY());
} else {
// onWheelButton/RightButtonClick
gp.unselectCell(e.getX(), e.getY());
}
}
});
add(gp);
setSize(new Dimension(500,500));
setVisible(true);
}
}
public class GridPainter extends JComponent {
private final int rows;
private final int columns;
private boolean[][] isSelected; // selection state of cells
public GridPainter(int rows, int columns) {
this.rows = rows;
this.columns = columns;
isSelected = new boolean[rows][columns];
}
private int getRowSize() {return getHeight() / rows;}
private int getColSize() {return getWidth() / columns;}
private int[] resolveIndices(int x, int y) {
int i = y / getRowSize();
int j = x / getColSize();
return new int[] {i, j};
}
public void selectCell(int x, int y) {
int[] indices = resolveIndices(x, y);
int i = indices[0];
int j = indices[1];
isSelected[i][j] = true;
repaint();
}
public void unselectCell(int x, int y) {
int[] indices = resolveIndices(x, y);
int i = indices[0];
int j = indices[1];
isSelected[i][j] = false;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
int width = this.getWidth();
int height = this.getHeight();
// draw rows
int rowSize = getRowSize();
for (int i = 0; i < columns; i++) {
int yOffset = i * rowSize;
g2.drawLine(0, yOffset, width, yOffset);
}
// draw lines
int colSize = getColSize();
for (int j = 0; j < rows; j++) {
int xOffset = j * colSize;
g2.drawLine(xOffset, 0, xOffset, height);
}
// fill selected cells
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (isSelected[i][j]) {
Color oldColor = g2.getColor();
g2.setColor(Color.BLUE);
int x = j * colSize;
int y = i * rowSize;
int w = colSize;
int h = rowSize;
g2.fillRect(x, y, w, h);
g2.setColor(oldColor);
}
}
}
}
}