![](/img/trans.png)
[英]What's the easiest way for a Java Swing client to consumer a webservice?
[英]What's the easiest way to draw a (monochrome) array using a mouse with Swing?
我一直在寻找一种在屏幕上绘制黑白数组的方法。 这是一个简单的数组,只有 20x20。 我打算做的是用鼠标在数组上绘制,以便每个像素在单击时从黑色“切换”到白色并返回,然后将数组作为一组布尔值(或整数)传递给另一个函数。 目前我正在使用 Swing。 我记得曾经使用 Swing 在画布上绘图,但我仍然找不到实际用法。 我应该使用画布,还是依赖 JToggleButtons?
您可以简单地使用JFrame
(或其他 Swing 组件)并覆盖paint(Graphics)
方法来绘制布尔矩阵的表示(请注意,对于像JPanel
这样的轻量级组件,您应该覆盖paintComponent(Graphics)
。这将为您提供所需的单击和拖动功能(使用单个 Swing 组件的网格很难实现)。
正如其他人评论的那样,AWT Canvas
不会为您提供 Swing 组件未提供的任何内容,您将在下面的示例中看到,我使用了JFrame
上也存在的createBufferStrategy
方法来确保非闪烁显示。
请注意,我的示例相当简单,因为它切换您拖动的每个像素,而不是单击操作确定您是处于“绘画”模式还是“擦除”模式,然后在拖动期间专门应用黑色或白色像素.
public class Grid extends JFrame {
private static final int SCALE = 10; // 1 boolean value == 10 x 10 pixels.
private static final int SIZE = 20;
private boolean[][] matrix = new boolean[SIZE][SIZE];
private boolean painting;
private int lastX = -1;
private int lastY = -1;
public Grid() throws HeadlessException {
setPreferredSize(new Dimension(SIZE * SCALE, SIZE * SCALE));
setResizable(false);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setBackground(Color.WHITE);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
painting = true;
tryAdjustValue(e.getPoint());
}
public void mouseReleased(MouseEvent e) {
painting = false;
lastX = -1;
lastY = -1;
}
});
addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
tryAdjustValue(e.getPoint());
}
public void mouseMoved(MouseEvent e) {
tryAdjustValue(e.getPoint());
}
});
}
private void tryAdjustValue(Point pt) {
int newX = pt.x / SCALE;
int newY = pt.y / SCALE;
if (painting && isInRange(newX) && isInRange(newY) && (newX != lastX || newY != lastY)) {
// Only invert "pixel" if we're currently in painting mode, both array indices are valid
// and we're not attempting to adjust the same "pixel" as before (important for drag operations).
matrix[newX][newY] = !matrix[newX][newY];
lastX = newX;
lastY = newY;
repaint();
}
}
private boolean isInRange(int val) {
return val >= 0 && val < SIZE;
}
public void paint(Graphics g) {
super.paint(g);
for (int x=0; x<SIZE; ++x) {
for (int y=0; y<SIZE; ++y) {
if (matrix[x][y]) {
g.fillRect(x * SCALE, y * SCALE, SCALE, SCALE);
}
}
}
}
public static void main(String[] args) {
Grid grid = new Grid();
grid.pack();
grid.setLocationRelativeTo(null);
grid.createBufferStrategy(2);
grid.setVisible(true);
}
}
为什么不将简单的 20 x 20 网格 JPanel 保存在 GridLayout(20, 20) 中,并在通过 MouseListener 的 mousePressed 方法单击时翻转面板的背景颜色。 您可以将面板保存在二维数组中,并在需要时查询它们的背景颜色。
您也可以为此使用 JLabels,但您必须记住将它们的不透明属性设置为 true。 JButton 或 JToggleButton 也可以工作,......选项几乎是无限的。 我不建议您使用 AWT(画布),因为它们不需要在功能上退步,因为 Swing 处理得很好。
如果您遇到了这个问题,为什么不回来向我们展示您的代码,我们将更好地为您提供更具体的帮助。
解决此问题的另一种方法是使用单个 JPanel 并覆盖其paintComponent 方法。 你可以给它一个 int[][] 数组作为它的模型,然后在paintComponent方法中根据模型的状态绘制任何所需颜色的矩形。 然后给它一个 MouseListener 来改变模型的状态并调用重绘。
例如,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class BlackWhiteGridPanel extends JPanel {
// can have multiple colors if desired
// public static final Color[] COLORS = {Color.black, Color.red, Color.blue, Color.white};
public static final Color[] COLORS = {Color.black, Color.white};
public static final int SIDE = 20;
private static final int BWG_WIDTH = 400;
private static final int BWG_HEIGHT = BWG_WIDTH;
private int[][] model = new int[SIDE][SIDE]; // filled with 0's.
public BlackWhiteGridPanel() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
myMousePressed(e);
}
});
}
private void myMousePressed(MouseEvent e) {
// find relative position of mouse press on grid.
int i = (e.getX() * SIDE) / getWidth();
int j = (e.getY() * SIDE) / getHeight();
int value = model[i][j];
// the model can only hold states allowed by the COLORS array.
// So if only two colors, then value can only be 0 or 1.
value = (value + 1) % COLORS.length;
model[i][j] = value;
repaint();
}
public int[][] getModel() {
// return a copy of model so as not to risk corruption from outside classes
int[][] copy = new int[model.length][model[0].length];
for (int i = 0; i < copy.length; i++) {
System.arraycopy(model[i], 0, copy[i], 0, model[i].length);
}
return copy;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int ht = getHeight();
for (int i = 0; i < model.length; i++) {
for (int j = 0; j < model[i].length; j++) {
Color c = COLORS[model[i][j]];
g.setColor(c);
int x = (i * width) / SIDE;
int y = (j * ht) / SIDE;
int w = ((i + 1) * width) / SIDE - x;
int h = ((j + 1) * ht) / SIDE - y;
g.fillRect(x, y, w, h);
}
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(BWG_WIDTH, BWG_HEIGHT);
}
private static void createAndShowGui() {
BlackWhiteGridPanel mainPanel = new BlackWhiteGridPanel();
JFrame frame = new JFrame("BlackWhiteGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.